【问题标题】:Android: ViewGroup, how to intercept MotionEvent and then dispatch to target or eat it on demand?Android:ViewGroup,如何拦截MotionEvent然后派发到目标或者按需吃掉?
【发布时间】:2011-08-21 09:02:18
【问题描述】:

鉴于有一个 ViewGroup 有几个孩子。至于这个 ViewGroup,我想让它为它的所有孩子管理所有 MotionEvent,这表示 VG 将
1. 能够在所有事件被分派到目标(孩子)之前拦截所有事件
2. VG会先消费事件,再判断是否进一步派发事件给目标子
3. DOWN, MOVE, UP,我想看他们相对独立,也就是说VG可以吃DOWN,但是给孩子MOVE和UP。

我已阅读 SDK 指南“处理 UI 事件”,我了解事件侦听器、处理程序、ViewGroup.onInterceptTouchEvent(MotionEvent) 和 View.onTouchEvent(MotionEvent)。

这是我的示例,

@Override
public boolean onInterceptTouchEvent (MotionEvent event) {
    if (MotionEvent.ACTION_DOWN == event.getAction()) {
        return true;
    }

    return super.onInterceptTouchEvent(event);
}

@Override
public boolean onTouchEvent(MotionEvent event) {
    if (MotionEvent.ACTION_DOWN == event.getAction()) {            
        return true;
    }
    else {
        if (!consumeEvent(event)) {
            // TODO: dispatch to target since I didn't want to eat event
            //return this.dispatchTouchEvent(event);     // infinite loop!!!
        }
    }


    return super.onTouchEvent(event);
}

为了能够吃掉一些事件,当DOWN事件发生时,我必须在上述两种方法中都返回true,因为SDK是这么说的。然后我可以在 onTouchEvent 中看到 MOVE 和 up。但是,就我而言,我不知道如何将事件发送给孩子。

以上dispatchTouchEvent导致无限循环,这是可以理解的,因为VG本身可能是目标。当时我不知道哪个是目标,MotionEvent 没有给出提示,所以 dispatchTouchEvent 完全没用。
有人帮我吗?谢谢。

【问题讨论】:

标签: android event-handling motion


【解决方案1】:

没有简单的方法可以从onInterceptTouchEvent 中找到源View,也没有“调度”这些事件的方法。您可以发送KeyEvents,但不能发送MotionEvents。

处理MotionEvents(例如拖放)的常用方法是通过不同的Views(通过实现OnTouchListener后的onTouch回调)处理MotionEvent.ACTION_DOWN事件,和MotionEvent.ACTION_MOVE 事件通过父Viewgroup 的onInterceptTouchEvent 方法。


但有些 LOC 说的远不止一堆词。我在这里有一个很好的例子:http://doandroids.com/blogs/tag/codeexample/


如果您在 View 本身中处理 ACTION_DOWN 事件,那么您可以将哪个 View 启动它存储在其他地方,并将该变量用于进一步的操作。事件绑定到同一个视图,直到被 ACTION_UP 或 ACTION_CANCEL 操作完成。

如果您需要在 ACTION_DOWN 期间跟踪 View 并在 ViewGroup 上执行操作,那么我建议您在 ViewGroup 中添加一个公共方法(例如 public boolean handleActionDown (View v, MotionEvent e) 将从 onTouch 回调中调用

【讨论】:

  • 谢谢。如果让子代处理 DOWN 并且父 VG 得到 MOVE 或 UP,它仍然无法在必要时将 MOVE/UP 调度到真实目标。对于孩子,第一个 DOWN 事件应该按需拦截。并且拦截规则适用于每个DOWN/MOVE/UP。我认为我的情况与您的拖放不太相似。
  • @fifth 我在回答中回复了,因为评论太长了。
  • 好的,知道了。先存储目标视图是关键,以后我可以调度它。
  • @fifth 是的。要么就是这样,要么开始根据 x 和 y 坐标猜测您的 View,这可能会很混乱。
  • @Aleadam,我正在考虑为每个视图安装一个监督 OnTouch 监听器。繁琐的工作是,如果添加了组件视图,我必须迭代每个孩子,而且我必须递归地这样做。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-02-03
  • 2013-07-17
  • 2018-05-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多