Android O: 触摸事件传递流程源码分析(下)

来源:互联网 发布:csgo mac 国服 知乎 编辑:程序博客网 时间:2024/05/17 09:12

前一篇博客中,我们分析了ViewGroup传递触摸事件的流程,详见:
Android O: 触摸事件传递流程源码分析(上)

本篇博客,我们主要来看一下View传递触摸事件的流程。


ViewGroup在分发事件时,会调用dispatchTransformedTouchEvent方法,
将MotionEvent分发给合适的Child View或ViewGroup。
对于Child View而言,dispatchTransformedTouchEvent函数,
最终还是会调用View的dispatchTouchEvent方法。

现在我们就来看看View的dispatchTouchEvent方法:

public boolean dispatchTouchEvent(MotionEvent event) {    // If the event should be handled by accessibility focus first.    if (event.isTargetAccessibilityFocus()) {        // We don't have focus or no virtual descendant has it, do not handle the event.        if (!isAccessibilityFocusedViewOrHost()) {            return false;        }        // We have focus and got the event, then use normal event dispatch.        event.setTargetAccessibilityFocus(false);    }    ............

从上面的代码可以看出,与ViewGroup处理MotionEvent的过程一致,
View也会先针对Accessibility Focus事件进行处理。

如果事件要求Accessibility Focus,但当前View不具备这种能力,
那么分发结束,直接返回false;
如果当前View具有Accessibility Focus能力,那么收到这种类型的事件后,
直接将MotionEvent对应的Flag置为false。


我们继续跟进代码:

//用于保存最终的结果,记录事件是否被当前View消费掉boolean result = false;//这部分应该和测试相关if (mInputEventConsistencyVerifier != null) {    mInputEventConsistencyVerifier.onTouchEvent(event, 0);}//收到新开始的事件,清除旧有的记录信息final int actionMasked = event.getActionMasked();if (actionMasked == MotionEvent.ACTION_DOWN) {    // Defensive cleanup for new gesture    stopNestedScroll();}//与ViewGroup一样,需要进行安全性检测,避免View被恶意程序覆盖if (onFilterTouchEventForSecurity(event)) {    //从注释来看,此处处理鼠标相关的输入,不用特意关注    if ((mViewFlags & ENABLED_MASK) == ENABLED && handleScrollBarDragging(event)) {        result = true;    }    //View存在onTouchListener时,onTouchListener优先消费    ListenerInfo li = mListenerInfo;    if (li != null && li.mOnTouchListener != null            && (mViewFlags & ENABLED_MASK) == ENABLED            && li.mOnTouchListener.onTouch(this, event)) {        result = true;    }    //然后才是View调用onTouchEvent消费事件    //View的onTouchEvent函数,会根据事件的类型进行相应的处理    if (!result && onTouchEvent(event)) {        result = true;    }}//仍然是测试相关if (!result && mInputEventConsistencyVerifier != null) {    mInputEventConsistencyVerifier.onUnhandledEvent(event, 0);}// Clean up after nested scrolls if this is the end of a gesture;// also cancel it if we tried an ACTION_DOWN but we didn't want the rest// of the gesture.// 事件处理完毕或ACTION_DOWN未处理, 清楚记录if (actionMasked == MotionEvent.ACTION_UP ||        actionMasked == MotionEvent.ACTION_CANCEL ||        (actionMasked == MotionEvent.ACTION_DOWN && !result)) {    stopNestedScroll();}return result;

至此,View的事件分发流程分析完毕。
可以看出,由于View不需要继续将事件分发给Child View,
因此它需要管理的状态较少,事件处理的逻辑也比ViewGroup简单。

大致上来说,View处理事件的主要逻辑如下图所示:

阅读全文
'); })();
0 0
原创粉丝点击
热门IT博客
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 泡泡屋 91泡泡屋 网红泡泡屋 泡泡配方 每天泡泡脚 泡泡效果 泡泡塑料 怎么泡泡菜 泡泡包装 泡泡泥教程 泡泡枪 泡泡水 配方 泡泡眼 泡泡球 泡泡做法 泡泡胶图片 泡泡泥图片 泡泡贴 泡泡棒 泡泡沙 泡泡头 泡泡刺 泡泡手 泡泡猪 泡泡粉 泡泡面 泡泡鼠 泡泡王 泡泡羊 泡泡仔 泡泡蛙 泡泡脚 泡泡字 泡泡菜 泡泡石 泡泡枪内部结构图 泡泡的制作方法 泡泡机图片 舞台泡泡机价格 小泡泡机 儿童泡泡机 电动泡泡机