【Android View】View 的事件分发机制

Activity 的构成

在这里插入图片描述

以Activity的setContentView方法为入口,查看源码可知:
一个Activity包含一个Window对象,这个对象是由PhoneWindow来实现的。PhoneWindow将DecorView作为整个应用窗口的根View,而这个DecorView又将屏幕分为两个区域,即TitleViewContentView,而我们正常做应用所写的布局正是展示在ContentView中的。

View 的点击事件分发机制

什么是点击事件分发

当我们点击屏幕时,就产生了点击事件。这个事件被封装成了一个类Motionevent而当这个motionevent产生后,那么系统就会将这个moment传递给view的层级Motionevent在view中的层级传递的过程就是点击事件分发

在这个过程中主要涉及三个必须了解的方法:
dispatchTouchEvent(MotionEvent me): 该方法负责分发事件
onInterceptTouchEvent(MotionEvent me):该方法负责拦截事件
onTouchEvent(MotionEvent me):该方法负责响应事件

当点击事件产生后,事件首先会传递给当前的activity,这会调用activity的dispatchTouchEvent方法,当然具体的事件处理工作都是交由activity中的PhoneWindow来完成的,然后PhoneWindow再把事件处理工作交给DecorView,再由DecorView将事件处理工作交给根ViewGroup。

一个完整的事件序列是由ACTION_DOWN开始,以UP结束的。所以如果是DOWN事件,则说明现在的事件是一个新事件序列,这需要初始化之前的状态。

分发原则,如果本View没有拦截,则交由子View处理,如果拦截了,则本事件的MOVE和UP等事件均由本View拦截并处理,同时不再调用onInterceptTouchEvent方法。

注意:onInterceptTouchEvent方法默认返回false,即不拦截。如果想要让ViewGroup拦截事件,则应在自定义的ViewGroup中重写这个方法。

遍历ViewGroup的子元素,如果子元素能够接受到点击事件,则交由子元素处理,如果不能,则遍历下一个子View。遍历VIewGroup的子元素时是倒叙遍历的,即从最上层的子View向内层遍历。

如果有子View,则调用子View的dispatchTouchEvent(event)方法,如果ViewGroup没有子View,则调用super.dispatchTouchEvent(event)方法。分发过程中,如果OnTouchListener不为null并且onTouch方法返回True,则表示事件已被消费,就不会执行onTouchEvent(event)

通过ListenerInfo拿到mListenerInfo,从其中拿到mOnClickListener并调用其onClick方法。

点击时间事件分发的传递规则

以伪代码解释三个方法的关系:

public boolean dispatchTouchEvent(MotionEvent me){
	if(onInterceptTouchEvent(me){
		result = onTouchEvent(me);
	}else{
		result = child.dispatchTouchEvent(me);
	}
	return result;
}

当点击事件产生后会由Activity处理,传递给PhoneWindow,再传递给DecorView,最后传递给顶层的ViewGroup。对于根viewGroup,点击事件首先传递给它的dispatchTouchEvent方法,如果onInterceptTouchEvent方法返回true,则表示它要拦截该事件,那么就把该事件交由onTouchEvent方法处理;否则交给它的子元素的dispatchTouchEvent()处理。如此循环,最终传递给底层的View。
总之,onInterceptTouchEvent为true则拦截,否则继续向下传递。

当点击时间传给底层的View时,如果其onTouchEvent()方法返回true,则事件由该View消耗并处理,反之则表示该View不响应该事件,则传递给父View的onTouchEvent处理;而如果父View的onTouchEvent仍旧返回false,则继续向上回传。
总之,onTouchEvent为true,则处理;反之,向上传递。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值