如何在ViewGroup级别处理所有TouchEvent(即将所有事件冒泡到包含viewgroup)

时间:2012-07-12 21:14:36

标签: android android-layout

我想在容器级别处理所有触摸事件。换句话说,我希望所有触摸事件都达到容器级别。现在我发现,如果触摸的位置没有落在视图组包含的UI组件上,TouchEvents只会到达包含的ViewGroup。包含的UI元素处理TouchEvent,它不会冒泡到容器。有谁知道如何保证所有触摸事件都达到顶级容器?

为了清楚起见,用几个按钮,几个编辑文本和几个复选框来描绘活动。典型的形式。通常情况下,我看到每个UI组件都会捕获落在它上面的TouchEvent,并且容器不是更明智的。因此,我想知道容器/视图组如何被告知在其区域内任何地方的所有触摸,无论该区域是否被按钮,空白区域或编辑文本占用。

2 个答案:

答案 0 :(得分:8)

这是我解释您的问题的方式:

你有这样的View树

  • ViewGroup G.
    • 查看A
    • 查看B
    • ...

并且你希望G处理触摸时创建的MotionEvent,即使它被A,B,...中的任何一个消耗了......


如何:

我会给你两个选择。取决于您是否要忽略消费

  1. 每个孩子
  2. 仅选择儿童
  3. 使用以下模板之一:

    1. 覆盖G

      中的dispatchTouchEvent()
      // In G
      @Override
      public boolean dispatchTouchEvent(MotionEvent event) {
           super.dispatchTouchEvent(event);
      
           // Handle event here instead of using an OnTouchListener
      
           return true;
       }
      
    2. 在每个应忽略其消耗的子项中重写dispatchTouchEvent()

      • 忽略一些孩子

        // In every child whose consumption should be ignored
        @Override
        public boolean dispatchTouchEvent(MotionEvent event) {
             super.dispatchTouchEvent(ev);
        
             return false; // false means "I did not consume the event"
         }
        
      • 不要忘记设置你的听众

        // In G, before touch should be recognized
        setOnTouchListener(new OnTouchListener() {
            @Override
            public boolean onTouch(View v, MotionEvent event) {
                // Handle event here
        
                return true; // true means "I did consume the event"
            }
        });
        
    3. 以代码行测量,选项1更简单。选项2是为了防止你需要特殊处理A,B ......

答案 1 :(得分:1)

我知道现在已经很晚了,但我认为未来的读者可能会想看看ViewGroups.onInterceptTouchEvent()