Android 事件分发 之 全家桶

你好! 确实,我今天面试,然后被问到了事件分发, 跟人家聊的稀碎,所以回来仔细查阅了点儿资料和源码,特此记录一下。

事件分发基础

  1. 分发事件的组件,也可以说是分发事件者:
    Activity:四大组件之一,这个就不过多解释了

    View:是Android中所有Ui组件的基类,即Android中所有的组件都继承自View。其中,View中一个比较重要的子类就是ViewGroup

    ViewGroup:通常作为其他View的容器,当然也包含普通的View。通过ViewGroup与View这种关系,构成了Android中的整个View树的结构,比如FrameLayout不仅是一个ViewGroup同时也是一个View,里面可以包含各种不同的View和ViewGroup

在Android中,各种操作其实基本上都是依靠各种手势,比如说单击,滑动,拖动等各种操作,经过前面对ViewGroup的解释,不同的View经常会处在不同的层级,所以就出西安了个问题,我们该如何让不同的View响应特定的操作呢?以及不同的View之间会不会有滑动冲突的问题呢?答案是肯定会有的。那要是想知道怎么解决这种问题,就要从View的各种机制以及各种事件的分发过程及分发对象来了解了

  1. MotionEvent对象
    MotionEvent: 顾名思义,它是Android用来记录各种事件的一个对象。而Android事件分发也是分发的它。
    前面提到的事件是指 用户触摸到了屏幕所产生的事件,然后主要的事件有:
事件触发场景单次事件流触发的次数
MotionEvent.ACTION_DOWN在屏幕按下时1次
MotionEvent.ACTION_MOVE在屏幕上滑动时0次或多次
MotionEvent.ACTION_UP在屏幕抬起时0次或1次
MotionEvent.ACTION_CANCLE滑动超出控件边界时0次或1次

按下、滑动、抬起、取消这几种事件组成了一个事件流。事件流以按下为开始,中间可能有若干次滑动,以抬起或取消作为结束。
而每个MotionEvent中封装了许多与各种事件 发生位置相关的函数以及各种相关的事件类型,每个MotionEvent都包含了一系列动作,比如当手指触摸屏幕的一瞬间,系统就会产生一系列的触摸事件对象,每个触摸事件对象都代表着不同的动作,比如按下、滑动、抬起、取消等动作,这些动作分别对应着上表中的几个事件,每个事件流一般都是以按下(ACTION_DOWN)开始,然后中间可能没有或者有若干个滑动(ACTION_MOVE)事件,最后以抬起(ACTION_UP)结束,如果事件被拦截还会触发取消事件(ACTION_CANCLE),这个一般就是你滑动到屏幕外边, 然后事件就会被取消,总而言之,Android 事件分发的对象就是MotionEvent对象,当MotionEvent对象产生之后,系统会将这个事件向下分发给最终能够消费此事件的View

3.事件分发的主要方法

方法名作用ActivityViewGroupView
dispatchTouchEvent()主要用来分发事件存在存在存在
onInterceptTouchEvent()主要用来进行事件的拦截×存在×
onTouchEvent()主要用来 进行事件的处理存在存在存在

其实ViewGroup类中,实际是没有onTouchEvent方法的,但是由于ViewGroup继承自View,而View拥有onTouchEvent方法,故ViewGroup的对象也是可以调用onTouchEvent方法的。故在表格中表明ViewGroup中存在onTouchEvent方法的。
然后Activity因为它是需要将事件首先向下分发的,所以不需要onInterceptTouchEvent方法,那View呢?View就是正好与它相反,因为View下面没有子View了,所以事件本身就需要被View拦截,至于消不消费该事件则是onTouchEvent的事儿了

4.事件分发的大体流程

	Android事件分发是从Activity的dispatchTouchEvent()方法开始,然后
通过一系列的传递分发给ViewGroup的dispathcTouchEvent方法,然后如果当前
ViewGroup不拦截事件,则该事件会继续向子View分发事件,然后以此类推直到被
某个View将事件消费,或者如果没有任何View消费此事件,事件会从最深层的View
依此将事件传给父View的onTouchEvent方法,如果还没有消费最后会传到Activity
的onTouchEvent方法里,由Activity进行处理。
	其中,如果在某个ViewGroup拦截了该事件,则事件不会再向子View分发,而是
会调用该ViewGroup的onTouchEvent()方法处理该事件,当然该事件是否处理
还是主要看onTouchEvent方法的返回值,如果onTouchEvent()方法返回
true,表示事件就此消费,反之,返回false表示事件没有被消费,将交由父
View的onTouchEvent方法进行处理,如果父View一直没有处理,则最后将交给
Activity的onTouchEvent()进行处理
	然后还有就是,如果分发的过程中事件被某个View消费了,比如说是
ACTIONG_DOWN事件,当该事件被处理了之后,后面的ACTIONG_MOVE、ACTIONG_UP
事件将会被处理该事件的那个View直接接收,也就是说一旦某个事件被某
个View处理了,后面的一系列事件不再判断是否拦截这些事件,而是直接接收,
因为一个完整的事件流基本上都是以ACTIONG_DOWN事件开始,中间可能没有或者
加上若干个ACIOTN_MOVE,然后以ACTIONG_UP结束

事件分发源码分析

将于2021/12/11补充!

事件分发流程分析

将于2021/12/12补充!

关于onTouch()和onClick()

将于2021/12/13补充!

我是入梦,谢谢你的观看我的博客,觉着好用的话,麻烦帮忙点个赞呗,谢谢啦~ 如果有什么错误,请随时联系我噢~QQ:897589417

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值