如何在两个重叠的视图上捕获onTouch事件?

时间:2014-10-14 04:02:46

标签: android overlapping touch-event

布局

* Container is a relative layout contains two custom views: OuterView1 and InnerView2 * Outer View1 is a custom view, matching the parent’s size (full screen) * Inner View2 is also a custom view, laid on top of OuterView1 overlapping it.

  • Container是一个相对布局,包含两个自定义视图:OuterView1和InnerView2
  • 外部View1是自定义视图,与父级的大小(全屏)匹配
  • Inner View2也是一个自定义视图,位于OuterView1的顶部,重叠它。

在OuterView1和InnerView2上,我想在onSingleTapConfirmed()和onFling()上捕获这些触摸事件。 OuterView1和InnerView2重叠的区域,我想将控件传递给两个视图的触摸事件方法。

我试过了:

容器类

    @Override
    public boolean onInterceptTouchEvent(MotionEvent ev) {
        outerView1.onTouchEvent(ev);
        innerView2.onTouchEvent(ev);
        return false;
    }

OuterView1类

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        gesture.onTouchEvent(event);
        return true;
    }

gesture是GestureDetector.SimpleOnGestureListener的一个实例,带有onDown(),onFling()和onSingleTapConfirmed()方法的日志语句

InnerView2类

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        gesture.onTouchEvent(event);
        return true;
    }

gesture是GestureDetector.SimpleOnGestureListener的一个实例,带有onDown(),onFling()和onSingleTapConfirmed()方法的日志语句

通过这种方法,我始终在两个视图的onDown()方法中进行回调。但我没有看到onSingleTapConfirmed()和onFling()方法的一致行为

当我点击红色圆圈(在屏幕截图中)三次,我有三种不同的行为

  • 首先尝试(所需行为)

    10-14 09:03:14.155: I/OuterView1(27776): OuterView1.onDown()
    10-14 09:03:14.155: I/InnerView2(27776): InnerView2.onDown()
    10-14 09:03:14.155: W/GestureDetector(27776): [pen gesture] isConsideredDoubleTap - timeout
    10-14 09:03:14.155: I/InnerView2(27776): InnerView2.onDown()
    10-14 09:03:14.460: I/OuterView1(27776): OuterView1.onSingleTapConfirmed()
    10-14 09:03:14.460: I/InnerView2(27776): InnerView2.onSingleTapConfirmed()
    
  • 第二次尝试(只有一个视图获得onSingleTapConfirmed())

    10-14 09:04:11.615: I/OuterView1(27776): OuterView1.onDown()
    10-14 09:04:11.615: I/InnerView2(27776): InnerView2.onDown()
    10-14 09:04:11.615: W/GestureDetector(27776): [pen gesture] isConsideredDoubleTap - timeout
    10-14 09:04:11.615: I/InnerView2(27776): InnerView2.onDown()
    10-14 09:04:11.915: I/OuterView1(27776): OuterView1.onSingleTapConfirmed()
    
  • 第三次尝试(一个视图获取onFling()而另一个获取onSingleTapConfirmed())

    10-14 09:04:04.180: I/OuterView1(27776): OuterView1.onDown()
    10-14 09:04:04.180: I/InnerView2(27776): InnerView2.onDown()
    10-14 09:04:04.180: W/GestureDetector(27776): [pen gesture] isConsideredDoubleTap - timeout
    10-14 09:04:04.180: I/InnerView2(27776): InnerView2.onDown()
    10-14 09:04:04.255: I/InnerView2(27776): InnerView2.onFling()
    10-14 09:04:04.480: I/OuterView1(27776): OuterView1.onSingleTapConfirmed()
    

你能帮我在OuterView1和InnerView2上捕捉触摸事件吗?

1 个答案:

答案 0 :(得分:11)

因此,在重叠视图的情况下,触摸事件从最顶层的子节点发送到后面的一个,然后是另一个后面的第二个子节点,依此类推。 但是,如果最顶层的孩子要使用触摸事件(即在接收触摸事件时处理它),那么该视图下面的视图将不会接收到触摸事件。

如果onTouchEvent返回'true',那么它告诉视图管理器它已经处理了触摸并且不希望将事件分派给其他视图。如果您希望该视图下方的视图也能接收到触摸,那么您希望从第一个视图的onTouchEvent返回'false',在您的情况下是Innerview。

此外,在您的代码中,我注意到您以编程方式将触摸事件从容器类调度到2个视图。即使仅单击OuterView,这也会导致InnerView接收触摸。如果你想要那个功能,那就没关系。如果您希望InnerView仅在触摸时获取事件,那么您不希望容器类在这两个视图上显式调用onTouchEvent。视图层次结构将为您完成。

关于在BOTH视图上接收onFling或onSingleTapConfirmed - (假设你想让触摸事件也进入后面的视图,你从InnerView的onTouchEvent返回'false')InnerView已经将事件传递给它背后的视图,所以它没有得到手势的结束,以实现一个刚刚发生的fling和类似的onSingleTapConfirmed。如果您仍想获得那些,那么您可能必须在OuterView检测到的手势结束时以编程方式发送触摸事件。这意味着,如果OuterView得到了一个轻松的手势,那么它也是对InnerView的一种投射,所以以编程方式使这个手势也发生在InnerView上。 这是非常复杂的,并且在层次结构中向后调度不是常见的事情。

希望我对此并不感到困惑。随意询问我是否还不清楚,我会再试一次。

这会有所帮助:Handling TouchEvents in a ViewGroup