View的事件分发、拦截和消费流程全解析,看这一篇已经够了

                         【声明】:未经许可,禁止转载!

· 案例

    今天,我们来看一个这样的案例,目的是熟悉android事件分发、拦截的流程。不多bb,我们看例子。

例子如上图,ViewGroupA内嵌ViewGroupB存放着一个ImageView,一个简单明了的布局,让我们以此来揭开View的事件分发机制。

代码非常简单,ViewGroupA和ViewGroupB分别重写了dispatchTouchEvent()、onInterceptTouchEvent()、onTouchEvent();而ImageView因为不是容器没有onInterceptTouchEvent(),只是在这三个方法打印了Log,主要是分析我们的Log看看事件分发、拦截的流程。我只贴一个ViewGroupA的代码, 其他基本一样我就不贴出来了。

/**
 * @Created by xww.
 * @Creation time 2018/8/16.
 */

public class ViewGroup_A extends FrameLayout {
    public ViewGroup_A(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    @Override
    public boolean dispatchTouchEvent(MotionEvent ev) {
        Log.i("---ViewGroup_A---", "dispatchTouchEvent: " + ev.getAction());
        return super.dispatchTouchEvent(ev);
    }

    @Override
    public boolean onInterceptTouchEvent(MotionEvent ev) {
        boolean isIntercept = false;
        Log.i("---ViewGroup_A---", "onInterceptTouchEvent: " + ev.getAction() + " ----是否拦截:" + isIntercept);
        return isIntercept;
    }

    @Override
    public boolean onTouchEvent(MotionEvent ev) {
        boolean isTouch = false;
        Log.i("---ViewGroup_A---", "onTouchEvent: " + ev.getAction() + "  ----是否消费:" +isTouch);
        return isTouch;
    }
}

· 流程(Children是ImageView,0表示DOWN事件,1表示UP事件)

注意:down ---> up 是完整性事件,activity默认设置不消费。

    一、不拦截、不消费。

它的完整流程是:

activity(分发 DOWN事件)---> A (未拦截分发) ---> B (未拦截分发) ---> children(分发)---> children(未消费)---> B (未消费)---> A (未消费) ---> activity(未消费 UP事件

    二、不拦截、仅children消费。

activity(分发 DOWN事件)---> A (未拦截分发) ---> B (未拦截分发) ---> children(分发)---> children(消费  UP事件

    三、不拦截、仅B消费。

activity(分发 DOWN事件)---> A (未拦截分发) ---> B (未拦截分发) ---> children(分发)---> children(未消费)---> B (消费 UP事件

    四、不拦截、仅A消费。

activity(分发 DOWN事件)---> A (未拦截,分发) ---> B (未拦截,分发) ---> children(分发)---> children(未消费)---> B (未消费)---> A (消费 UP事件) 

    五、B拦截,不消费。

activity(分发 DOWN事件)---> A (未拦截,分发) ---> B (拦截,未分发)---> B (未消费)---> A (未消费) ---> activity(未消费 UP事件

B拦截了事件,children即收不到事件传递,由谁拦截由谁结束分发,那将由谁开始处理onTouchEvent()事件。

    六、A拦截,不消费。

activity(分发 DOWN事件)---> A (拦截,未分发)---> A (未消费) ---> activity(未消费 UP事件

    七、不拦截,children不分发,仅B消费。

发现onTouchEvent()事件全部消失了,即使你有消费它,但是children不分发,相当于所有View的onTouchEvent()事件根本没被消费,看我们的日志及屏幕的Toast情况。

可以看到,Log的确有事件的分发,到了children时我们将它终止分发,所有的onTouchEvent()不消费,屏幕也无法Toast成功。所以大多数情况下,我们不会去终止事件的分发。

©版权所有:https://blog.csdn.net/smile_Running/article/details/81740593

猜你喜欢

转载自blog.csdn.net/smile_Running/article/details/81740593
今日推荐