onTouch和onClick 的那些事儿

onclick与ontouch和scroll监听冲突的解决方法 用于解决一个界面内同时存在多个不同类型监听冲突的方法,实现类似QQHD版窗口拖动滚动点击效果 立即下载

事件的分发流程可以说基本上已经阐述清楚,在阅读本篇文章之前,请先阅读下面几篇文章:

Android 事件分发之基础
Android事件分发之源码分析
Android事件分发之流程分析

还有一个问题是 Android 事件传递过程中 onTouch 和 onClick 事件在整个事件过程中是如何进行事件传递的,下面主要是关于 onTouch 、 onClick 与事件传递过程中调用的先后顺序,将从如下几个方面介绍:

源码中的 onTouch() 方法
源码中的 onClick() 方法
onTouch() 与 onClick() 方法之间的关系
总结

源码中的onTouch()方法
当要设置触摸事件的监听时,使用到 View 类中的 OnTouchListener 接口,然后通过 setOnClickListener 设置对触摸事件的监听,然后就可以通过具体的事件类型去执行某些操作,onTouch() 方法就是接口 OnTouchListener 中定义的方法,在 View 的 dispatchTouchEvent() 方法中调用,下面时 onTouch方法在源码中的具体调用:
//事件分发public boolean dispatchTouchEvent(MotionEvent event) {    …    //默认返回值    boolean result = false;    …    //注意判断条件    if (onFilterTouchEventForSecurity(event)) {        if ((mViewFlags & ENABLED_MASK) == ENABLED && handleScrollBarDragging(event)) {            result = true;        }        ListenerInfo li = mListenerInfo;        //注意判断条件        if (li != null && li.mOnTouchListener != null                && (mViewFlags & ENABLED_MASK) == ENABLED                && li.mOnTouchListener.onTouch(this, event)) {            result = true;        }        if (!result && onTouchEvent(event)) {            result = true;        }    }   …    return result;}复制代码
上述代码中,先来看一下最外面的条件 onFilterTouchEventForSecurity() 方法,只关心该方法的返回值即可,源码如下:
/** * 如果事件正常分发返回true,如果事件被丢弃返回false * @see #getFilterTouchesWhenObscured /public boolean onFilterTouchEventForSecurity(MotionEvent event) {    //noinspection RedundantIfStatement    if ((mViewFlags & FILTER_TOUCHES_WHEN_OBSCURED) != 0            && (event.getFlags() & MotionEvent.FLAG_WINDOW_IS_OBSCURED) != 0) {        // Window is obscured, drop this touch.        return false;    }    return true;}复制代码
所以该方法正常情况下返回 true,然后关键的条件主要就是 ListenerInfo 是否为 null,mOnTouchListener 是否为 null,以及 onTouch() 方法的返回值,下面是 ListenerInfo 初始化的源码部分,具体如下:
//getListenerInfo()的具体调用public void setOnTouchListener(OnTouchListener l) {    getListenerInfo().mOnTouchListener = l;}//ListenerInfo的初始化ListenerInfo getListenerInfo() {    if (mListenerInfo != null) {        return mListenerInfo;    }    mListenerInfo = new ListenerInfo();    return mListenerInfo;}复制代码
显然,当通过 setOnTouchListener() 方法设置触摸事件的监听时就初始化了 ListenerInfo,同在在设置触摸事件监听的时候 mOnTouchListener != null 成立,最后 onTouch() 方法的返回值决定了 dispatchTouchEvent() 方法是否返回 true。所以,当设置了触摸监听事件且 onTouch() 方法返回 true 时,表示事件就此处理也就不再向子 View 传递了,同时,onTouchEvent() 方法也就不再执行,返回 false 则 onTouchEvent() 方法还会执行。
源码中的onClick()方法
当要设置点击事件的事件监听时,使用到 View 类中的 OnClickListener 接口,然后通过 setOnClickListener 设置对单击事件的监听,然后就可以通过具体的事件类型去执行某些操作,onClick() 方法就是 OnClickListener 接口中定义的方法,在 View 的 onTouchEvent() 方法中调用,在下文中也会进一步得到验证,下面是 onClick() 方法在源码中的具体调用:
//事件处理public boolean onTouchEvent(MotionEvent event) {    …    if (((viewFlags & CLICKABLE) == CLICKABLE ||            (viewFlags & LONG_CLICKABLE) == LONG_CLICKABLE) ||            (viewFlags & CONTEXT_CLICKABLE) == CONTEXT_CLICKABLE) {        switch (action) {            case MotionEvent.ACTION_UP:                …                //如果执行了该方法,其返回值就是onTouchEvent()的返回值                performClick();                …                break;        }        return true;    }    return false;}复制代码
上面代码中至少找到了 onClick() 方法的调用位置,下面是 performClick() 方法:
/
* * 主要回调了 OnClickListener */public boolean performClick() {    final boolean result;    final ListenerInfo li = mListenerInfo;    if (li != null && li.mOnClickListener != null) {        playSoundEffect(SoundEffectConstants.CLICK);        //调用了OnClickListener接口中的onClick()方法        li.mOnClickListener.onClick(this);        result = true;    } else {        result = false;    }    sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_CLICKED);    return result;}复制代码
显然,只要我们在代码中通过 setOnClickListener() 方法设置了对单击事件的监听,则对应 View 的 onTouchEvent() 方法返回 true,当然事件就此消费,反之返回 false,那么 onTouch 与 onClick 之间的调用顺序如何,它们之间会互相影响吗,下面就会从案列的角度了解它们之间的关系。
onTouch()与onClick()方法之间的关系
还是之前的案例,MLinearLayout 嵌套 MRelativeLayout,MRelativeLayout 嵌套 MTextView,三个 View 都只是重写了与它们自身相关的事件分发,然后为 MTextView 设置对触摸事件、单击事件的监听,具体如下:
@Overrideprotected void onCreate(Bundle savedInstanceState) {    super.onCreate(savedInstanceState);    setContentView(R.layout.activity_main);    findViewById(R.id.textView).setOnTouchListener(new View.OnTouchListener() {        @Override        public boolean onTouch(View v, MotionEvent event) {            Log.i(“Event”, “TextView-------onTouch---------------return:” + false);            return false;        }    });    findViewById(R.id.textView).setOnClickListener(new View.OnClickListener() {        @Override        public void onClick(View v) {            Log.i(“Event”, “TextView-------onClick”);    }    });}复制代码

让 onTouch() 返回 false,查看日志如下:

结论:设置了对触摸事件的监听,onTouch() 方法 false 时 onTouchEvent() 方法在 onTouch() 方法之后执行,事件就此消费,接着接受 ACTION_DOWN 之后的一系列事件,途中使用鼠标,故没有 ACTION_MOVE 事件,还有在 onTouch() 方法返回 false 的情况下 onClick() 执行了。

让 onTouch() 返回 true,查看日志如下:

结论 :当 onTouch() 返回 true 的时候,正如前面所述 onTouchEvent() 将不会再执行,故 onClick() 也就不会再执行。
总结
onTouch() 方法的返回值决定了 onTouchEvent() 方法要不要执行,如果 onTouch() 返回 true,则 onTouchEvent() 不会再执行,返回 false ,则 onTouchEvent() 继续执行,而 onClick() 的回调是在 onTouchEvent() 方法中调用,onTouchEvent() 不执行则 onClick() 不执行。

作者:躬行之
链接:https://juejin.im/post/5de677da518825124f53930a
来源:掘金
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

详谈Android中onTouch与onClick事件的关系(必看) 这几天遇到点关于Android的触摸事件相关的,还跟onClick有关,暂且记下: LinearLayout分别设置了onTouchListener,onClickListener,onLongClickListener及onTouchEvent回调 1、在屏幕上触摸之后基本的执行流程如下: onTouch,action=0 onTouchEvent,action=0 onTouch,action=2 onTouchEvent,action=2 onTouch,action=2 onTouchEvent,action=2 onTouch,action=1 onTouchEvent,actio 立即下载

相关推荐

M2DGR数据集在一些SLAM框架上的配置与运行:ORB-SLAM系列、VINS-Mono、LOAM系列、FAST-LIO系列、hdl_graph_slam

为了说明以上这些SLAM框架的测试与数据集适配,以M2DGR数据集为例进行各自的配置与运行,方便我以后适配自己的数据集,运行的SLAM框架包括:ORB-SLAM2、ORB-SLAM3、VINS-Mono、A-LOAM、LeGO-LOAM、LIO-SAM、LVI-SAM、FAST-LIO2、FAST-LIVO、Faster-LIO、hdl_graph_slam。实验基于Ubuntu20.04,其中ORB、VINS-Mono、和LOAM系列的安装参考我以前的博客,有详细的安装方法,其他的框架在后面会简单介绍一下

zardforever123的博客 1万+

Android开发详解之onTouch和onClick详解

android组件中的onTouch,onClick,onLongClick事件发生先后顺序和关联: 一,onTouch返回false 首先是onTouch事件的down事件发生,此时,如果长按,触发onLongClick事件; 然后是onTouch事件的up事件发生,up完毕,最后触发onClick事件。 二,onTouch返回true 首先是onTouch事件的down事

eclipse_xu 1万+

NX二次开发入门必看:手把手教你搭建开发环境

想顺利开展nx二次开发,第一步就是配置好开发环境。本文详细讲解从安装准备到环境调试的完整流程,结合实际操作细节,帮你避开常见坑点,快速进入nx二次开发的实战阶段。

weixin_31569663的博客 1457

Android中事件传递机制的总结

  事件传递虽然算不上某个单独的知识点,但是在实际项目开发中肯定会碰到,如果不明白其中的原理,那在设计各种滑动效果时就会感到很困惑。 关于事件的传递,我们可能会有以下疑问: 事件是如何传递的 事件是如何处理的 自定义view的时候,事件也冲突了怎么解决 带着这三个疑问,我们来总结一下事件传递机制是怎么回事。   一、事件分发的原理: 1、事件是如何传递的: (1)首...

weixin_34112208的博客 303

【精品5万字图文详解】特征平台建设方案与最佳实践

关键词:特征工程、特征平台、特征存储、特征服务、机器学习、数据工程摘要:本文全面介绍了特征平台的建设方案与最佳实践,从特征工程的基本概念出发,深入剖析了特征平台的核心组件、架构设计和实现方法。文章通过生动的类比和实例,使读者能够轻松理解特征工程的重要性及特征平台如何解决企业在机器学习过程中面临的数据管理挑战。同时,详细探讨了主流开源特征平台的对比分析、系统设计要点、实际落地案例以及未来发展趋势,为企业构建高效特征平台提供了全面的指导和参考。想象一下,小明是一位热爱烹饪的小学生。有一天,他想做一道美味的菜肴送

AI天才研究院 952

【深度学习驱动流体力学】采集OpenFOAM仿真数据作为AI模型训练数据集与卷积神经网络搭建到预测(一站式完整代码实现)

采集OpenFOAM仿真数据作为AI模型训练数据集与卷积神经网络搭建到预测(一站式完整代码实现)

源代码杀手的博客 1414

单击事件(onClick())与触摸事件(onTouch())的区别

       这里就不介绍单击事件和触摸事件了,概念很简单 。那么屏幕上的一个View组件,Android是如何区分应当触发onTouch事件还是onClick事件呢?        Android是按什么次序将事件传递的,又在什么情况下判定为消耗了该事件?        下面通过一个例子来说明(例子很简单,耐心看完,一看就懂)。 步骤: (1)修改新建项目 的res/layout目录下的...

qq_36473318的博客 1万+

STM32F103C8T6驱动DHT11温湿度传感器程序

本程序基于 STM32F103C8T6 微控制器,通过 GPIO 模拟单总线通信时序实现对 DHT11 温湿度传感器的数据采集,主机采用拉低数据线的方式触发传感器启动,并通过检测高电平持续时间区分逻辑“0”和“1”,依次读取湿度和温度的整数数据及校验位,经过校验后将有效结果存入缓存数组,实现对环境温湿度的周期性测量与处理。

加斯顿工程师的博客 200

Android 事件分发 之 全家桶

你好! 确实,我今天面试,然后被问到了事件分发, 跟人家聊的稀碎,所以回来仔细查阅了点儿资料和源码,特此记录一下。就是从基础,流程,源码等多个层面进行了一个比较全面的分析,学习~

chaseDreamer_的博客 2042

【Halcon-2D测量】add_metrology_object_rectangle2_measure 函数功能(用于向2D计量模型中添加旋转矩形(rectangle2类型)计量对象)

HALCON算子add_metrology_object_rectangle2_measure解析摘要 该算子是HALCON 2D计量模块的核心算子,用于添加旋转矩形计量对象并配置测量参数。主要功能包括:定义旋转矩形几何轮廓(中心坐标、主轴角度、长短半长);生成垂直于矩形边界的测量区域;设置边缘提取预处理参数(高斯平滑、振幅阈值)。关键注意事项:MeasureLength1必须小于矩形长短半长;角度参数Phi需使用弧度单位;多线程需同步模型句柄。该算子适用于方形螺母、PCB板边框等矩形零件的精密测量,需与a

weixin_45590420的博客 1223

RestFul API 详解

RESTful API 经常也被叫做 REST API,它是基于 REST 构建的 API。RESTful API 可以让你看到 URL+Http Method 就知道这个 URL 是干什么的,让你看到了 HTTP 状态码(status code)就知道请求结果如何。

wynn的博客 7581

直播平台软件开发,Android代码模拟触摸、点击及滑动等事件

这实现原理就是模拟两个MotionEvent (按下和提起) 然后用一个View 来处理这个Event。以上就是 直播平台软件开发,Android代码模拟触摸、点击及滑动等事件,更多内容欢迎关注之后的文章。直播平台软件开发,Android代码模拟触摸、点击及滑动等事件。二、Instrumentation实现模拟键盘鼠标事件。例如,模拟对某个view的点击事件。一、应用中模拟物理和屏幕点击事件。

云豹网络科技 1525

Android oom_adj 更新原理(一)

通过之前的两篇博文《lmkd 机制详解》和《lmkd中adj score的算法剖析》中,根据计算出来的 min_score_adj 选择大于该值的 oom_adj 的进程进行 kill 处理。oom_adj 随着应用状态的不同其值也是伴随着变化的。本文将通过源码剖析 oom_adj 更新的原理。

私房菜 2652

模拟手指点击滑动事件

一、需求:下载完apk并安装后,希望能不用人为操作就实现特定位置的点击跟滑动。这个需求要实现有几种方法,下面讲讲尝试过的使用MotionEvent去模拟用户手指点击跟滑动屏幕事件的实现。**二、思路:** 主要用到的是onTouch常用的4个事件:1、ACTION_DOWN: 表示按下了屏幕,第一个执行也是必然执行的方法。2、ACTION_MOVE: 表示为移动手势,会不断的执行直到触摸停止。

Jimbin的博客 1万+

数学建模模型总结

这是本人在两年内准备参加数学建模竞赛搜集到的模型资料,已经经过了本人的筛选和整理,希望能够对准备参加数学建模竞赛的学弟学妹们提供一些帮助!

老版QQ原生表情gif动态

这是老版的QQ表情,不过全是动态的的,Windows照片查看器是不会动的,可以右击用浏览器打开查看,再说一遍是老版的,只是分享给宁愿用老版也要动态的人。

Android : 模拟点击performClick()/模拟长按performLongClick()/模拟onTouch事件

【代码】Android : 模拟点击performClick()/模拟长按performLongClick()/模拟onTouch事件。

火星男孩的分享空间 2031

IMSL CNL 7.0.0 (x86-64)Crack

IMSL CNL 7.0.0 (x86-64)Crack intel的算法库破解文件,这是C++版本的破解文件

Android 关于View事件分发(onTouch、onTouchEvent、onClick、onLongClick的关系及原理)(一)

事件分发、事件冲突

weixin_54087854的博客 2925

ssm框架搭建

这个是一个在idea上成功跑起来的ssm框架项目,保存在这里方便以后使用直接下载

Android通过onTouch事件实现单击,双击,长按

一般采用延时做法。 private int mClickcount; // 点击次数 private int mDownX; private int mDownY; private int mMoveX; private int mMoveY; private int mUpX; private int mUpY; private long mLastDownTim

LikeSidehu的专栏 5734

onTouch,onClick冲突详解

View事件分发详解之onTouch,onClick,LongClick ONE Goal,ONE Passion! 概述: ViewGroup和View的分发.[http://blog.youkuaiyun.com/fengltxx/article/details/49330343]介绍一个OnTouchEvent中事件流程 @Override public boolean onTo

fengltxx的博客 5414

Android中onTouch方法的执行过程以及和onClick执行发生冲突的解决办法

$*********************************************************************************************$博主推荐:风萧兮兮易水寒,“天真”一去兮不复还。如何找到天真的那份快乐。小编倾力推荐app:天真无谐下载方式:豌豆荚,应用宝,360手机助手,百度手机助手,安卓,91市场搜索:天真无谐关注我们:查看详情$...

weixin_30455365的博客 434

Android_onTouch onTouchEvent 与 onClick的区别和先后调用关系

我们会经常在代码中看到触屏事件的处理,有时候使用onTouch,有时候使用了onTouchEvent,还有的时候使用了onClick,那么我们有没有对这三个方法进行过思考: 三者有什么区别呢? 要是三者都在代码中出现,应该是怎样的调用关系呢? 首先,我先把结论给出来: onTouch, onTouchEvent, onClick,三个方法的调用顺序是: onTouch ----> o...

c++ 中的符号-> 2277

Android中onTouch事件和onClick事件冲突问题解决

android中onTouch事件和onClick事件冲突

2614

Android onTouchEvent, onClick及onLongClick的调用机制

针对屏幕上的一个View控件,Android如何区分应当触发onTouchEvent,还是onClick,亦或是onLongClick事件? 在Android中,一次用户操作可以被不同的View按次序分别处理,并将完全响应了用户一次UI操作称之为消费了该事件(consume),那么Android是按什么次序将事件传递的呢?又在什么情况下判定为消费了该事件? 搞清楚这些问题对...

iteye_9890的博客 613

Android中onTouch与onClick事件的关系

这几天遇到点关于Android的触摸事件相关的,还跟onClick有关,暂且记下: LinearLayout分别设置了onTouchListener,onClickListener,onLongClickListener及onTouchEvent回调 1、在屏幕上触摸之后基本的执行流程如下: onTouch,action=0 onTouchEvent,action=0 onTou

mydreamongo的专栏 2万+

Android事件分发机制完全解析,带你从源码的角度彻底理解(上)

Android事件分发机制完全解析,带你从源码的角度彻底理解(上) 分类: Android疑难解析2013-06-20 08:30 1901人阅读 评论(13) 收藏 举报 Android事件分发onTouchdispatchTouchEventonTouchEvent 转载请注明出处:http://blog.youkuaiyun.com/sinyu890807/article/de

pi9nc的专栏 6万+

【H5】 移动端的基本事件

【H5】 移动端的基本事件: 一、基础事件 1、PC端事件 onclick 鼠标点击触发 onmousedown 鼠标按下触发 onmousemove 鼠标移动触发 onmouseup 鼠标抬起触发 2、移动端触屏事件 ontouchstart 手指按下触发 ontouchmove 手指移动触发 onTouchend 手指抬起触发 3、PC端事件和移动端事件的区别 通...

舜岳的博客 6420
上一篇: Java对象为啥要实现Serializable接口?
下一篇: 使用 JS 来动态操作 css ,你知道几种方法?
妄想编程
博客等级 码龄8年 1粉丝 5原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值