OnClick不被调用,onTouchEvent不被调用的情况是onTouch的DOWN返回true

2023-10-20 08:32

本文主要是介绍OnClick不被调用,onTouchEvent不被调用的情况是onTouch的DOWN返回true,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

(1)首先没有设置OnClickListener的情况下,onTouch的返回值表示的就是View对点击事件是否消耗,如果在DOWN事件传递过来时返回false,那么剩下的MOVE直到UP的事件都不会被onTouch接收到;如果在DOWN事件返回true,那么剩下的直到UP的事件都会接受到,无论你之后的返回值。 
(2)在同时设置了OnTouchListener与OnClickListener之后,情况就有些复杂了: 
情况1:如果onTouch在DOWN时返回了true,那么onTouch就和(1)一样收到剩下的所有事件,但onClick就不会被执行; 
情况2:如果onTouch在DOWN时返回了false,与(1)不同的是,onTouch尽管在DOWN时返回了false,但之后的所有事件仍能接受到,并且onClick会在之后被调用。

3、原因解析 
首先解析这个问题其实很简单,就是一个View的关键函数dispatchTouchEvent,让我们直接来看代码:

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)onTouch调用return true;  }  if(onTouchEvent(event)){  //(2)onTouchEvent调用return true;  }  }  ... ...  return false;  
}  
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15

dispatchTouchEvent就是触摸时间分发的关键函数,相信看过相关解析的一定对这个很清楚,如果一个事件能够传递给当前View,那么一定会调用这个方法,返回值就是表示是否消耗此事件,那么我们来根据上面的规律进行分析: 
(1)如果没有设置OnClickListener,只设置了OnTouchListener,那么在代码(1)处就会调用onTouch,如果DOWN事件时返回了true,那么剩下的事件都会交由此View进行处理;如果返回了false,那么就会执行代码(2)处的onTouchEvent函数,如果设置了OnClickListener,就会在其中进行调用,如果没有设置,dispatchTouchEvent就会返回false,那么剩下的事件都不会交由此View进行处理; 
(2)如果同时设置了OnTouchListener与OnClickListener,那么我们再按上面的两种情况进行分析: 
情况1:onTouch在DOWN时返回了true,那么代码(1)处就得到了真的结果,直接就返回了true,可以知道后面代码(2)处的onTouchEvent函数不会被执行,那么自然你的OnClickListener就不起作用了,onClick就不会被执行; 
情况2:onTouch在DOWN时返回了false,那么代码(1)处就不会得到真的结果,后面代码(2)处的onTouchEvent函数就会得到执行,而如果你设置了OnClickListener,View就会处于CLICKABLE状态,那么onTouchEvent函数就会返回true,dispatchTouchEvent就会返回true,那么这时后面的事件由于DOWN时返回true,就会统统交由此View进行处理,自然你的onTouch中也能够监听到后面的所有事件!这样上面的情况就能够得到解释了。

4、总结 
这样我们就搞清楚了onTouch与onClick两种监听的相互关系,总的来说onTouch优先级更高,如果onTouch在DOWN中返回true,那么onClick就不会执行;但如果onClick被设置,那么一定程度上也会影响onTouch。关于具体的触摸事件传递机制我之后会配合设计模式写一个全面的博文,加强自己的认识和理解。

这篇关于OnClick不被调用,onTouchEvent不被调用的情况是onTouch的DOWN返回true的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/245956

相关文章

Python调用另一个py文件并传递参数常见的方法及其应用场景

《Python调用另一个py文件并传递参数常见的方法及其应用场景》:本文主要介绍在Python中调用另一个py文件并传递参数的几种常见方法,包括使用import语句、exec函数、subproce... 目录前言1. 使用import语句1.1 基本用法1.2 导入特定函数1.3 处理文件路径2. 使用ex

Idea调用WebService的关键步骤和注意事项

《Idea调用WebService的关键步骤和注意事项》:本文主要介绍如何在Idea中调用WebService,包括理解WebService的基本概念、获取WSDL文件、阅读和理解WSDL文件、选... 目录前言一、理解WebService的基本概念二、获取WSDL文件三、阅读和理解WSDL文件四、选择对接

Java调用Python代码的几种方法小结

《Java调用Python代码的几种方法小结》Python语言有丰富的系统管理、数据处理、统计类软件包,因此从java应用中调用Python代码的需求很常见、实用,本文介绍几种方法从java调用Pyt... 目录引言Java core使用ProcessBuilder使用Java脚本引擎总结引言python

java如何调用kettle设置变量和参数

《java如何调用kettle设置变量和参数》文章简要介绍了如何在Java中调用Kettle,并重点讨论了变量和参数的区别,以及在Java代码中如何正确设置和使用这些变量,避免覆盖Kettle中已设置... 目录Java调用kettle设置变量和参数java代码中变量会覆盖kettle里面设置的变量总结ja

如何在页面调用utility bar并传递参数至lwc组件

1.在app的utility item中添加lwc组件: 2.调用utility bar api的方式有两种: 方法一,通过lwc调用: import {LightningElement,api ,wire } from 'lwc';import { publish, MessageContext } from 'lightning/messageService';import Ca

【LabVIEW学习篇 - 21】:DLL与API的调用

文章目录 DLL与API调用DLLAPIDLL的调用 DLL与API调用 LabVIEW虽然已经足够强大,但不同的语言在不同领域都有着自己的优势,为了强强联合,LabVIEW提供了强大的外部程序接口能力,包括DLL、CIN(C语言接口)、ActiveX、.NET、MATLAB等等。通过DLL可以使用户很方便地调用C、C++、C#、VB等编程语言写的程序以及windows自带的大

Android中如何实现adb向应用发送特定指令并接收返回

1 ADB发送命令给应用 1.1 发送自定义广播给系统或应用 adb shell am broadcast 是 Android Debug Bridge (ADB) 中用于向 Android 系统发送广播的命令。通过这个命令,开发者可以发送自定义广播给系统或应用,触发应用中的广播接收器(BroadcastReceiver)。广播机制是 Android 的一种组件通信方式,应用可以监听广播来执行

string字符会调用new分配堆内存吗

gcc的string默认大小是32个字节,字符串小于等于15直接保存在栈上,超过之后才会使用new分配。

京东物流查询|开发者调用API接口实现

快递聚合查询的优势 1、高效整合多种快递信息。2、实时动态更新。3、自动化管理流程。 聚合国内外1500家快递公司的物流信息查询服务,使用API接口查询京东物流的便捷步骤,首先选择专业的数据平台的快递API接口:物流快递查询API接口-单号查询API - 探数数据 以下示例是参考的示例代码: import requestsurl = "http://api.tanshuapi.com/a

struts2中的json返回指定的多个参数

要返回指定的多个参数,就必须在struts.xml中的配置如下: <action name="goodsType_*" class="goodsTypeAction" method="{1}"> <!-- 查询商品类别信息==分页 --> <result type="json" name="goodsType_findPgae"> <!--在这一行进行指定,其中lis是一个List集合,但