如何在两个重叠视图上捕获 onTouch 事件? [英] How to capture onTouch events on two overlapping views?

查看:37
本文介绍了如何在两个重叠视图上捕获 onTouch 事件?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

布局

!* Container 是一个相对布局,包含两个自定义视图:OuterView1 和 InnerView2* Outer View1 为自定义视图,匹配父级尺寸(全屏)* Inner View2 也是一个自定义视图,放置在 OuterView1 之上.

  • Container 是一个相对布局,包含两个自定义视图:OuterView1 和 InnerView2
  • Outer View1 是一个自定义视图,匹配父级的尺寸(全屏)
  • Inner View2 也是一个自定义视图,位于 OuterView1 之上,重叠.

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

On both OuterView1 and InnerView2, I want to capture these touch events onSingleTapConfirmed() and onFling(). The area where both OuterView1 and InnerView2 are overlapping, I want the control to be passed to touch event methods of both views.

我试过了:

容器类

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

OuterView1 类

OuterView1 class

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

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

gesture is an instance of GestureDetector.SimpleOnGestureListener with log statements for onDown(), onFling() and onSingleTapConfirmed() methods

InnerView2 类

InnerView2 class

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

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

gesture is an instance of GestureDetector.SimpleOnGestureListener with log statements for onDown(), onFling() and onSingleTapConfirmed() methods

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

With this approach, I consistently get callback in onDown() methods of both views. But I don’t see a consistent behaviour on onSingleTapConfirmed() and onFling() methods

当我点击红色圆圈(在屏幕截图中)三下时,我得到了三种不同的行为

When I tapped in the red circle (in the screenshot) three times and I got three different behaviour

  • 第一次尝试(期望的行为)

  • First try (desired behaviour)

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())

  • Second try (Only one view gets 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())

  • Third try (One view gets onFling() and another gets 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 上捕获触摸事件吗?

    Could you help me capture touch events on both OuterView1 and InnerView2?

    推荐答案

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

    So in the case of overlapping views - touch events are dispatched from the topmost child to the one behind, then another one behind the 2nd child and so on. However, if the topmost child were to consume the touch event (i.e. handle it upon receiving it) then the views underneath that view will not receive the touch events.

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

    If the onTouchEvent returns 'true' then it is telling the view manager that it has handled the touch and does not want the event to be dispatched to other views. If you want the view underneath that view to receive the touch too then you want to return 'false' from the onTouchEvent for the first view, in your case the Innerview.

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

    Also, in your code I noticed you are programmatically dispatching touch events to the 2 views from the container class. This causes the InnerView to receive touch even when ONLY the OuterView is clicked. If you want that functionality then it is ok. If you want InnerView to get the events only when it is touched then you dont want the container class to call onTouchEvent explicitly on those 2 views. The view hierarchy will do it for you.

    关于在两个视图上接收 onFling 或 onSingleTapConfirmed -(假设您想让触摸事件也传递到后面的视图,您从 InnerView 的 onTouchEvent 返回false")InnerView 已经将事件传递给它背后的视图,所以它没有结束手势来意识到刚刚发生了一个甩动,对于 onSingleTapConfirmed 也是如此.如果您仍然想获得这些,那么您可能必须在 OuterView 检测到的手势结束时以编程方式调度触摸事件.意思是,如果 OuterView 有一个投掷手势,那么它也是对 InnerView 的投掷,因此以编程方式使该手势也发生在 InnerView 上.这非常复杂,在层次结构中向后调度触摸不是一件常见的事情.

    About receiving onFling or onSingleTapConfirmed on BOTH views - (assuming you want to let the touch events to go through to the views behind as well, you return 'false' from the onTouchEvent for InnerView) the InnerView has already passed the event to the view behind it, so it doesnt get the end of the gesture to realize that a fling just occured and similarly for onSingleTapConfirmed. If you want to still get those then you may have to dispatch touch events programmatically at the end of the gesture as detected by the OuterView. Meaning, if OuterView got a fling gesture then it was a fling for the InnerView too and so programmatically make that gesture happen for the InnerView as well. This is quite complicated and dispatching touches backwards in the hierarchy is not a usual thing.

    希望我没有让你感到困惑.如果我没有说清楚,请随时问我,我会再试一次.

    Hopefully I havent confused you on this. Feel free to ask if I haven't been clear and I will try again.

    这会很有帮助:在 ViewGroup 中处理 TouchEvents

    这篇关于如何在两个重叠视图上捕获 onTouch 事件?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

    查看全文
    登录 关闭
    扫码关注1秒登录
    发送“验证码”获取 | 15天全站免登陆