31

我有一个线性布局,上面有一个 Button 和一个 TextView。我为活动编写了一个 OnTouchEvent。如果我触摸屏幕,代码工作正常,但如果我触摸按钮,代码不起作用。对此有什么可能的解决方案?

public boolean onTouchEvent(MotionEvent event) {
   int eventaction=event.getAction();


   switch(eventaction)
   {
   case MotionEvent.ACTION_MOVE:
      reg.setText("hey");


   break;
   }
   return true;

  }
4

7 回答 7

105

问题在于 Android 如何处理触摸事件的操作顺序。每个触摸事件都遵循以下模式(简化示例):

  1. Activity.dispatchTouchEvent()
  2. ViewGroup.dispatchTouchEvent()
  3. View.dispatchTouchEvent()
  4. View.onTouchEvent()
  5. ViewGroup.onTouchEvent()
  6. 活动.onTouchEvent()

但是事件只会跟随链直到它们被消耗onTouchEvent()(意味着有人从或侦听器返回 true )。如果您只是触摸屏幕上的某个位置,则没有人对该事件感兴趣,因此它会一直流向您的代码。但是,对于按钮(或其他可点击View),它会消耗触摸事件,因为它对它感兴趣,因此流程在第 4 行停止。

如果要监视进入 Activity 的所有触摸,则需要重写dispatchTouchEvent(),因为始终首先onTouchEvent()调用的内容是最后调用的,并且只有在没有其他人捕获该事件的情况下才调用。但是,请注意不要在此处使用事件,否则子视图将永远无法获取它们,并且您的按钮将无法单击。

public boolean dispatchTouchEvent(MotionEvent event) {
   int eventaction=event.getAction();

    switch(eventaction) {
      case MotionEvent.ACTION_MOVE:
          reg.setText("hey");
          break;
      default:
          break;
    }

    return super.dispatchTouchEvent(event);
}

另一种选择是将您的触摸处理代码放入自定义ViewGroup(如LinearLayout)并使用其onInterceptTouchEvent()方法允许父视图偷走并在必要时处理触摸事件。不过要小心,因为这种交互在新的触摸事件开始之前无法撤消(一旦你窃取了一个事件,你就窃取了它们全部)。

高温高压

于 2012-06-12T17:09:24.263 回答
4

让我在@Devunwired 的这篇出色的帖子中再添加一条评论。

如果您还在 View 上设置了 onTouchListener,那么它的 onTouch() 方法将在调度方法之后调用,但在任何 onTouchEvent() 方法之前调用,即在@Devunwired 的答案中介于 no.3 和 no.4 之间。

于 2014-01-16T14:39:42.400 回答
1

尝试将您的布局的descendantFocusability属性设置为 blocksDescendants

于 2012-06-12T17:01:47.703 回答
0

Activity::onTouchEvent仅当 Activity 窗口中的视图没有消耗/处理事件时才会调用。如果您触摸ButtonButton将消耗事件,因此 Activity 将无法处理它。

查看以下文章,了解有关 Android 触摸事件处理管道的更多信息。

http://pierrchen.blogspot.jp/2014/03/pipeline-of-android-touch-event-handling.html

于 2014-03-09T03:12:21.747 回答
0

你也可以试试onUserInteraction()

@Override 
public void onUserInteraction(){
     //your code here
     super.onUserInteraction();
}

很适合我!

于 2016-10-27T09:09:08.093 回答
0

public boolean dispatchTouchEvent(MotionEvent event)改为使用onTouchEvent()

于 2018-10-12T14:12:48.090 回答
0
RecyclerView list_view = findViewById(R.id.list_view);
list_view.addOnItemTouchListener(new RecyclerView.SimpleOnItemTouchListener(){
    @Override
    public boolean onInterceptTouchEvent(@NonNull RecyclerView rv, @NonNull MotionEvent e) {
        View child = rv.findChildViewUnder(e.getX(), e.getY());
        Log.i("Hello", "World");
        return false;
    }
});
于 2018-12-31T12:50:17.147 回答