OnTouchEvent不能处理子视图

时间:2012-06-12 16:58:37

标签: android ontouchlistener

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

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


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


   break;
   }
   return true;

  }

7 个答案:

答案 0 :(得分:91)

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

  1. Activity.dispatchTouchEvent()
  2. ViewGroup.dispatchTouchEvent()
  3. View.dispatchTouchEvent()
  4. View.onTouchEvent()
  5. ViewGroup.onTouchEvent()
  6. Activity.onTouchEvent()
  7. 但是事件只会在消耗之前跟随链接(意味着某人从onTouchEvent()或监听器返回true)。如果你只是触摸屏幕上的某个地方,没有人对这个事件感兴趣,所以它一直流到你的代码。但是,在按钮(或其他可点击的View)的情况下,它会消耗触摸事件,因为它对它感兴趣,因此流程在第4行停止。

    如果你想要监控进入你的Activity的所有触摸,你需要覆盖dispatchTouchEvent(),因为首先调用的是onTouchEvent(),最后调用一个Activity,并且只有在没有其他人的情况下才会调用抓住了这个事件。但是,请注意不要在此处使用事件,否则子视图将永远不会获取它们,并且您的按钮将无法点击。

    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()方法允许父视图窃取并处理触摸事件必要时。但要小心,因为这种互动是一个在新的触摸事件开始之前无法撤消的互动(一旦你偷了一个事件,你就会把它们全部偷走)。

    HTH

答案 1 :(得分:4)

让我再加上@Devunwired对这篇优秀文章的评论。

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

答案 2 :(得分:1)

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

答案 3 :(得分:0)

仅当Activity WIndow中的非视图消耗/处理事件时,才会调用

Activity::onTouchEvent。如果您触摸ButtonButton将消耗这些事件,因此活动将无法处理它。

有关Android Touch事件处理管道的更多信息,请查看以下文章。

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

答案 4 :(得分:0)

您还可以尝试onUserInteraction()

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

适合我!

答案 5 :(得分:0)

public boolean dispatchTouchEvent(MotionEvent event)上使用onTouchEvent()

答案 6 :(得分: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;
    }
});