当用户单击时,将触发大小写MotionEvent.ACTION_DOWN。释放点击时,将触发案例MotionEvent.ACTION_UP。
我有兴趣确定ACTION_UP是否在ACTION_DOWN后 3 秒内未触发。意思是,如果自用户点击以来已经过去了 3 秒并且尚未发布,我想知道,本质上是试图确定长点击。
有没有办法做这样的事情?
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
break;
case MotionEvent.ACTION_UP:
break;
}
通常,检测长按的正确方法是实现View.OnLongClickListener。这比自己检测更容易,更不容易出错,并且可以确保您的应用程序与系统的其余部分很好地配合。
对于自定义View
,应将implements View.OnLongClickListener
添加到类声明中,将setOnLongClickListener(this);
添加到构造函数中,然后将onLongClick()
方法添加到类中:
public boolean onLongClick (View v) {
// Handle long-click
}
如果您的View
不是自定义的,您可以像这样添加侦听器:
theView.setLongClickable(true);
theView.setOnLongClickListener(new View.OnLongClickListener() {
public boolean onLongClick(View v) {
// Handle long-click
}
});
更新:好的,我已经做了一些挖掘,虽然这是我曾经使用过的每个视图的正确方法,但它实际上不适用于 SeekBars,而这正是提问者正在使用的。 这一事实没有记录在SeekBar
文档中,但实验表明它是真实的,并且挖掘源代码说明了原因:SeekBar.onTouchEvent()
不调用super.onTouchEvent()
。如果合适,performLongClick()
是在View.onTouchEvent()
中调用的。
如果有必要,我会实现它的方式是Handler.postDelayed()
. 在ACTION_DOWN,我会发布(例如 3000 毫秒延迟)一个处理长按到Handler
的Runnable
,我会在ACTION_UP取消它。 因此,任何小于延迟的按压最终都不会调用Runnable
,但如果延迟后没有发生ACTION_UP,那就是。
也就是说,我提醒你重新考虑这样做。 长按SeekBar
是什么意思? 如果用户拖动"拇指"的时间超过延迟时间,突然间,您有一个长按,这可能不是故意的。 每次移动拇指时,您都可以取消和重置延迟,这需要长按一个位置几秒钟。 但很少能完全静止;事实上,握住拇指却几秒钟不移动它是很困难的。 因此,您可以对拇指位置进行最小更改,从而重置延迟。 如果有必要,这就是我会做的,但我必须说这是一种非常奇怪的用户体验。
它简单明了。您需要获取时间戳来评估事件之间的时差,您可以通过以下示例进行操作:
private static int TIME_MARGIN = 3; //seconds
private Date d1 = null;
public void OnWhatEverOnClickEvent(Event event){
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
d1 = new Date();
break;
case MotionEvent.ACTION_UP:
Date d2 = new Date();
if((d2.getTime() - d1.getTime()) >= (TIME_MARGIN * 1000L)){
//its a long click due to 3 seconds hold, do something here
}
break;
}
}
但是,正如@Darshan计算所说,您应该更好地利用View.OnLongClickListener
这是一种无忧无虑的方法。
当用户单击时,启动一个新线程来轮询按钮的当前状态(或引入一个新标志,该标志在DOWN
中设置并在UP
中重置。线程可以每 100 毫秒轮询一次此状态或标志,并使用内部时间戳来确定是否已过去 3 秒。如果是这样,它可以触发一个新事件以启动长时间单击的操作