无法同时处理点击和触摸事件
我正在尝试处理触摸事件并单击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; } });** 
通过这种方式可以实现这两个事件