Android-View 点击&触摸事件优先级

一直很好奇,View 点击&触摸事件它们触发的优先级是怎么样,哪个先执行,哪个后执行,返回只true、false对后续执行有什么影响呢?主要分析onClick,onLongClick,onTouch,onTouchEvent这4个函数,有兴趣的可以一起往下看。

源码分析基于Android-23

简述作用
  1. onTouch&onTouchEvent

都是可以监听Touch事件,区别在于,前者是通过setOnTouchListener进行注册,后者只要重写即可; 2. onClick 监听点击事件; 3. onLongClick 监听长按事件。

OnTouchListener&onTouchEvent的调用关系
//View类中
public boolean dispatchTouchEvent(MotionEvent event) {
       //省略部分代码
      if (onFilterTouchEventForSecurity(event)) {
             //省略部分代码
            ListenerInfo li = mListenerInfo;
            if (li != null && li.mOnTouchListener != null
                    && (mViewFlags & ENABLED_MASK) == ENABLED
                    && li.mOnTouchListener.onTouch(this, event)) {//1
                result = true;
            }

            if (!result && onTouchEvent(event)) {//2
                result = true;
            }
        }
        //省略部分代码
        return result;
    } 
  • 注释1:当设置了setOnTouchListener,那么li.mOnTouchListener就不为空,li.mOnTouchListener的onTouch函数就会被触发;
  • 注释2:如果li.mOnTouchListener的onTouch函数被触发并返回ture,那么重写的onTouchEvent就不会被触发;
onTouch&onTouchEvent的调用关系小结
  • li.mOnTouchListener的onTouch函数没有比触发或返回false,那么重写onTouchEvent才会被触发;
  • mOnTouchListener的onTouch方法优先级比onTouchEvent高;
流程图

1.png

onClick&onLongClick&onTouchEvent的调用关系
//View类中
public boolean onTouchEvent(MotionEvent event) {
            ......
            switch (action) {
                case MotionEvent.ACTION_UP:
                        ......
                        if (!mHasPerformedLongPress && !mIgnoreNextUpEvent) {//3
                            removeLongPressCallback();
                            ......
                           performClick();
                        }
                    ......
                    break;

                case MotionEvent.ACTION_DOWN:
                    ......
                    if (isInScrollingContainer) {//1
                        if (mPendingCheckForTap == null) {
                            mPendingCheckForTap = new CheckForTap();
                        }
                        postDelayed(mPendingCheckForTap, ViewConfiguration.getTapTimeout());
                    } else {
                        checkForLongClick(0);//2
                    }
                    break;

                case MotionEvent.ACTION_CANCEL:

                    removeTapCallback();//当发生canel,则移除判断点击任务
                    removeLongPressCallback();//当发生canel,则移除判断长按任务
                    ......
                    break;

                case MotionEvent.ACTION_MOVE:
                    ......
                    if (!pointInView(x, y, mTouchSlop)) {
                        removeTapCallback();//当发生move事件,则移除判断tap的任务
                        if ((mPrivateFlags & PFLAG_PRESSED) != 0) {
                              ......
                            removeLongPressCallback();//当发生move事件,则移除判断长按任务
                        }
                    }
                    break;
            }
            return true;
        }
        return false;
    } 
  • 注释2:先分析这里点,假设isInScrollingContainer为false,则发送500毫秒延时任务执行长按;
  • 注释1:当View被滑动控件包裹,则isInScrollingContainer为true,发送100毫秒的延时任务来判断判断是tap事件还是滑动事件,100毫秒内没有任何滑动,则发送400毫秒延时任务执行长按;
  • 注释3:如果onLongClick没有被触发或者返回false,mHasPerformedLongPress 则为false,将移除长按任务,接着执行performClick,通过从ViewRootImpl得到的handle往主线程队列发送点击任务(主要是触发li.mOnClickListener.onClick),等待被执行;
OnClickListener&OnLongClickListenerOnTouchEvent&onTouchEvent的调用关小结
  • down事件,View被滑动控件包裹,发送100毫秒的延时任务来判断是tap事件还是滑动事件,接着发送400毫秒的延时任务判断是是否长按;
  • 如果onLongClick被触发并返回true,那么onClick则不会被触发;
被滚动控件包裹,为什么要先发送100毫秒的延时任务呢?

重点是要区分tap(点击或长按)、滚动,如果是点击事件,需要给View设置一个按下的效果,但如果这个事件最终是滚动事件,那么先有按下后再有松开,用户体验显示是不合理的,所以有这样的判断。

流程图

2.png

总结
  • OnTouchListener onTouch函数优先级比onTouchEvent高;
  • 当onTouchEvent被触发,onClick、onLongClick才有可能被执行,
  • 当onLongClick消费了事件,那么onClick将无法执行;
  • 点击事件实现,在up事件时,利用ViewRootImpl构建的handler,往主线程MessageQueue发一个runnable点击任务,等待被分发执行;
  • 长按事件实现,发送100毫秒延时任务判断是tap还是滑动,如果是tap,则再发送400毫秒延时任务执行长按;

有分析不对的地方请指出,互相学习,谢谢哦!

文末

要想成为架构师,那就不要局限在编码,业务,要会选型、扩展,提升编程思维。此外,良好的职业规划也很重要,学习的习惯很重要,但是最重要的还是要能持之以恒,任何不能坚持落实的计划都是空谈。

如果你没有方向,这里给大家分享一套由阿里高级架构师编写的《Android八大模块进阶笔记》,帮大家将杂乱、零散、碎片化的知识进行体系化的整理,让大家系统而高效地掌握Android开发的各个知识点。
在这里插入图片描述
相对于我们平时看的碎片化内容,这份笔记的知识点更系统化,更容易理解和记忆,是严格按照知识体系编排的。

一、架构师筑基必备技能

1、深入理解Java泛型
2、注解深入浅出
3、并发编程
4、数据传输与序列化
5、Java虚拟机原理
6、高效IO
……

在这里插入图片描述

二、Android百大框架源码解析

1.Retrofit 2.0源码解析
2.Okhttp3源码解析
3.ButterKnife源码解析
4.MPAndroidChart 源码解析
5.Glide源码解析
6.Leakcanary 源码解析
7.Universal-lmage-Loader源码解析
8.EventBus 3.0源码解析
9.zxing源码分析
10.Picasso源码解析
11.LottieAndroid使用详解及源码解析
12.Fresco 源码分析——图片加载流程

在这里插入图片描述

三、Android性能优化实战解析

  • 腾讯Bugly:对字符串匹配算法的一点理解
  • 爱奇艺:安卓APP崩溃捕获方案——xCrash
  • 字节跳动:深入理解Gradle框架之一:Plugin, Extension, buildSrc
  • 百度APP技术:Android H5首屏优化实践
  • 支付宝客户端架构解析:Android 客户端启动速度优化之「垃圾回收」
  • 携程:从智行 Android 项目看组件化架构实践
  • 网易新闻构建优化:如何让你的构建速度“势如闪电”?

在这里插入图片描述

四、高级kotlin强化实战

1、Kotlin入门教程
2、Kotlin 实战避坑指南
3、项目实战《Kotlin Jetpack 实战》

  • 从一个膜拜大神的 Demo 开始

  • Kotlin 写 Gradle 脚本是一种什么体验?

  • Kotlin 编程的三重境界

  • Kotlin 高阶函数

  • Kotlin 泛型

  • Kotlin 扩展

  • Kotlin 委托

  • 协程“不为人知”的调试技巧

  • 图解协程:suspend

在这里插入图片描述

五、Android高级UI开源框架进阶解密

1.SmartRefreshLayout的使用
2.Android之PullToRefresh控件源码解析
3.Android-PullToRefresh下拉刷新库基本用法
4.LoadSir-高效易用的加载反馈页管理框架
5.Android通用LoadingView加载框架详解
6.MPAndroidChart实现LineChart(折线图)
7.hellocharts-android使用指南
8.SmartTable使用指南
9.开源项目android-uitableview介绍
10.ExcelPanel 使用指南
11.Android开源项目SlidingMenu深切解析
12.MaterialDrawer使用指南
在这里插入图片描述

六、NDK模块开发

1、NDK 模块开发
2、JNI 模块
3、Native 开发工具
4、Linux 编程
5、底层图片处理
6、音视频开发
7、机器学习

在这里插入图片描述

七、Flutter技术进阶

1、Flutter跨平台开发概述
2、Windows中Flutter开发环境搭建
3、编写你的第一个Flutter APP
4、Flutter开发环境搭建和调试
5、Dart语法篇之基础语法(一)
6、Dart语法篇之集合的使用与源码解析(二)
7、Dart语法篇之集合操作符函数与源码分析(三)

在这里插入图片描述

八、微信小程序开发

1、小程序概述及入门
2、小程序UI开发
3、API操作
4、购物商场项目实战……

在这里插入图片描述

尾声

开发是需要一定的基础的,我是08年开始进入Android这行的,在这期间经历了Android的鼎盛时期,和所谓的Android”凉了“。中间当然也有着,不可说的心酸,看着身边朋友,同事一个个转前端,换行业,其实当时我的心也有过犹豫,但是我还是坚持下来了,这次的疫情就是一个好的机会,大浪淘沙,优胜劣汰。再等等,说不定下一个黄金浪潮就被你等到了。

这是我在这行工作10几年积累的一些资料,如果还想继续在这行业走下去的,或者现在打算跳槽,可以**私信【学习】**我愿意把资料免费分享给大家。
或者直接扫描下面二维码领取

请添加图片描述

Android学习PDF+架构视频+面试文档+源码笔记

  • 330页 PDF Android核心笔记

  • 几十套阿里 、字节跳动、腾讯、华为、美团等公司2020年的面试题

  • PDF和思维脑图,包含知识脉络 + 诸多细节

  • Android进阶系统学习视频

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值