Android事件分发机制

Android事件分发机制就是用户触摸屏幕时(View或ViewGroup派生的控件),将产生的点击事件(Touch事件 )。Touch事件的相关细节(发生触摸的位置、时间等)被封装成MotionEvent对象,系统把这个事件传递给一个具体的View去处理的整个过程。

Android的UI界面由Activity、ViewGroup、View及其派生类组成,一个点击事件发生后,按照Activity->ViewGroup->View的顺序进行事件传递的

事件类型分为四种,分别是Motion.ACTION_DOWN、Motion.ACTION_UP、Motion.ACTION_CANCEL。一般情况下,以DOWN事件开始,UP事件结束,中间有无数的MOVE事件的一系列事件就是事件列。事件列分发有3个方法,分别是dispatchTouchEvent()、onInterceptTouchEvent()、onTouchEvent()。dispatchTouchEvent()方法是分发(传递)点击事件的,onTouchEvent()方法是处理点击事件的,onInterceptTouchEvent()方法是判断是否拦截某个事件,这个方法只存在于ViewGroup,普通的View无该方法。

Android分发机制分为Activity对事件的分发、ViewGroup对事件的分发、View对事件的分发

Activity对事件的分发既当一个点击事件发生时,事件最先传到Activity的dispatchTouchEvent()方法中进行分发,通过源码我们可以看到调用了getWindow()的superDispatchTouchEvent()方法,而这里的getWindow()返回的是Window抽象类,其实就是PhoneWindow类,继承于Window抽象类,然后调用PhoneWindow的superDispatchTouchEvent()方法,而PhoneWindow的superDispatchTouchEvent()方法中又调用了DecorView的superDispatchTouchEvent()方法,DecorView是Activity的Window窗口中最根部的父容器,继承于FrameLayout,FrameLayout又继承于ViewGroup,由此Activity就将事件分发到ViewGroup中了,如果ViewGroup对事件进行了处理或传递,则getWindow()。superDispatchTouchEvent()就会返回true,相应的Activity的dispatchTouchEvent()方法就会返回true。反之getWindow().superDispatchTouchEvent()返回false,返回false的情况下就会调用Activity的onTouchEvent()方法,主要是对于处理边界外点击事件的判断:是否是DOWN事件,event的坐标是否在边界内等。无论true或false,事件都将传递分发到ViewGroup而Activity的事件分发就结束了。

从上面Activity事件分发可知,ViewGroup事件分发从DispatchTouchEvent()方法开始,ViewGroup每次事件分发都需调用onInterceptTouchEvent()询问是否拦截事件,如果返回值为false,即不拦截,通过for循环,遍历当前ViewGoup下的所有子View,判断当前遍历的子View,是不是正在点击的子View,从而找到当前被点击的子View,调用该子View的dispatchTouchEvent()方法,实现了点击事件从ViewGroup到子View的传递,如果该控件可点击,dispatchTouchEvent()的返回值必定是true,因此会导致条件判断成立,于是给ViewGroup的dispatchTouchEvent()直接返回了true。如果ViewGroup的onInterceptTouchEvent()返回值为true,及对点击事件进行拦截,不允许事件继续向子View传递,调用ViewGroup父类View的dispatchTouchEvent,其内部最终会调用onTouchEvent进行事件处理。

从上面ViewGroup事件分发机制知道,View事件分发从dispatchTouchEvent()开始。看源码可知,该方法中有三个判断条件皆为true时,View的dispatchTouchEvent()才返回true,否则执行onTouchEvent()方法。条件一是onTouchListener不为空,只要为该控件注册Touch事件,该onTouchListener就一定不为空,条件二是判断当前控件是否可点击,如果可点击,则为true,条件三是回调控件注册Touch事件的onTouchEvent()方法返回值为true。如果三个判断条件有一个不为true,那么就调用View的onTouchEvent()方法进行处理。在该方法中,判断该方法是否可点击,可点返回true,即onTouchEvent方法返回true,View的dispatchTouchEvent就返回true,不可点返回false,即onTouchEvent方法返回false,View的dispatchTouchEvent就返回false,这就与ViewGroup中的调用子View的dispatchTouchEvent()方法的返回值相对应起来了!

以上就是Android事件分发机制的理解,如有不对之处,请指教;

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值