无法同时处理点击和触摸事件
我正在尝试处理触摸事件并单击button上的事件。 我做了以下几点:
button.setOnClickListener(clickListener); button.setOnTouchListener(touchListener);
当任何一个监听器注册的东西工作正常,但是当我尝试使用它们时,只有触摸事件被触发。 任何解决方法? 我究竟做错了什么?
ClickListener
和TouchListener
之间有一个细微的但非常重要的区别。 TouchListener
在视图可以响应事件之前执行。 ClickListener
只有在视图处理后才会收到它的事件。
所以当你触摸你的屏幕时, TouchListener
被执行,当你的事件返回true
时, ClickListener
将永远不会得到它。 但是,如果按下设备的轨迹球,则应触发TouchListener
因为TouchListener
不会对其作出响应。
它有点棘手。
如果你设置了onTouchListener
你需要在ACTION_DOWN
返回true
,告诉系统我已经消费了这个事件,并且不会滴onTouchListener
其他的监听器。
但是,那么OnClickListener
将不会被解雇。
所以你可能会想,我会在那里做我的事情,并返回false
所以我也可以收到点击。 如果你这样做,它会工作,但你不会订阅其他即将到来的触摸事件( ACTION_MOVE
, ACTION_UP
)因此,唯一的select是在那里返回true
,但是那么你将不会收到任何点击事件,如我们所说先前。
所以你需要在ACTION_UP
手动执行view.performClick()
这将工作。
感谢@urSus的伟大答案
但在这种情况下,每个触摸将执行点击,即使ACTION_MOVE
假设你想分开move
事件和click
事件,你可以使用一个小技巧
定义一个boolean
字段,像这样使用:
@Override public boolean onTouch(View view, MotionEvent motionEvent) { switch (motionEvent.getAction() & MotionEvent.ACTION_MASK) { case MotionEvent.ACTION_DOWN: shouldClick = true; . . break; case MotionEvent.ACTION_UP: if (shouldClick) view.performClick(); break; case MotionEvent.ACTION_POINTER_DOWN: break; case MotionEvent.ACTION_POINTER_UP: break; case MotionEvent.ACTION_MOVE: //Do your stuff shouldClick = false; break; } rootLayout.invalidate(); return true; }
我想你在你的OnTouchListener
返回true
这将消耗事件,所以它不会被发送下来的任何进一步处理。
在旁注中,点击和触摸监听器有什么意义?
您应该在OnTouchListener
返回false,然后您的OnClickListener
也将被处理。
button.setOnTouchListener(this);
在这里实现接口和代码:
@Override public boolean onTouch(View view, MotionEvent motionEvent) { switch (view.getId()) { case R.id.send: switch(motionEvent.getAction()){ case MotionEvent.ACTION_DOWN: //when the user has pressed the button //do the needful here break; case MotionEvent.ACTION_UP: //when the user releases the button //do the needful here break; } break; } return false; }
为了在gridview中使这两个事件成为可能,只有通过如下返回监听器“false”,这对我才有效。
**GridView myView = findViewById(R.id.grid_view); myView.setOnTouchListener(new OnTouchListener() { public boolean onTouch(View v, MotionEvent event) { // ... Respond to touch events return false; } });**
通过这种方式可以实现这两个事件