Android触屏分发机制(一)

2024-05-14 15:48
文章标签 android 机制 分发 触屏

本文主要是介绍Android触屏分发机制(一),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

面试学校工作室HCI时曾被要求写类似知乎的界面逻辑,其中遇到了一个问题就是layout的onTouch和button的onClick冲突,解决的方法便是了解触屏分发机制。这段时间查阅了许多资料,具体了解Android的触屏分发机制是怎么实现的。
按钮的点击事件相信大家闭着眼睛都能写得出来了:

btn.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {Log.i(TAG, "on click");}});

如果说再给这个按钮添加一个onTouch事件,会输出怎样的结果呢?

btn.setOnTouchListener(new View.OnTouchListener() {@Overridepublic boolean onTouch(View v, MotionEvent event) {switch (event.getAction()) {case MotionEvent.ACTION_DOWN:Log.i(TAG, "on touch action down");break;case MotionEvent.ACTION_UP:Log.i(TAG, "on touch action up");break;}return false;}});

以下是输出结果:
这里写图片描述
可以看出,onTouch时间是在onclick之前执行的。我们可能会发现onTouch的方法中有一个返回值false,如果把它改为true,结果会怎样?
这里写图片描述
此时Button的onClick事件并没有执行!我们可以这样理解,当onTouch时间返回true时,相当于把当前的点击事件消费(拦截)掉了,从而无法把点击事件继续分发下去。那为什么会因为一个返回值而导致结果不同呢?其中View有一个重要的方法dispatchTouchEvent()可以解释其中的原因,当按钮点击时,会首先执行dispatchTouchEvent()这个方法。从字面的意思上理解dispatch有调度,分发的意思,按钮点击后则在这个方法中分发事件。往上查找,我们会发现View中有这个方法,我们看看其方法的主要部分:

 public boolean dispatchTouchEvent(MotionEvent event) {//省略一部分if (onFilterTouchEventForSecurity(event)) {//noinspection SimplifiableIfStatementListenerInfo 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;}

我们看看第二个if里的三个参数,
mListenerInfo:这个是我们在为Button设置onTouch事件时传递的参数,即new View.OnTouchListener(){//…},这个值不为null;
第二个参数则是判断按钮是否可用。
第三个参数li.mOnTouchListener.onTouch(this, event)为onTouch事件的返回值。
明显,当第三个参数返回为true时,result = true,否则为false。接着看下一个if语句,意思为当result为false时则执行onTouchEvent(event)这个方法,并赋值result;可见我们的onTouch事件的返回值为false时会执行onTouchEvent(event)方法。那我们在看看onTouchEvent方法是如何实现的:

public boolean onTouchEvent(MotionEvent event) {//省略一部分if (!focusTaken) {if (mPerformClick == null) {mPerformClick = new PerformClick();}if (!post(mPerformClick)) {performClick();}}//省略一部分}

其中经过种种判断(由于代码过长,就没有贴出来了),会进入performClick()这个方法:

public boolean performClick() {final boolean result;final ListenerInfo li = mListenerInfo;if (li != null && li.mOnClickListener != null) {playSoundEffect(SoundEffectConstants.CLICK);li.mOnClickListener.onClick(this);result = true;} else {result = false;}sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_CLICKED);return result;}

明显,我们可以看到在第6行执行了onClick事件,而mListenerInfo正是我们在为按钮添加onClick事件时传入的参数!
因此,我们可以总结一下点击按钮后事件是如何分发的:
这里写图片描述

Android触屏分发机制(二)http://blog.csdn.net/u010429311/article/details/50979578

这篇关于Android触屏分发机制(一)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



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

相关文章

java中反射(Reflection)机制举例详解

《java中反射(Reflection)机制举例详解》Java中的反射机制是指Java程序在运行期间可以获取到一个对象的全部信息,:本文主要介绍java中反射(Reflection)机制的相关资料... 目录一、什么是反射?二、反射的用途三、获取Class对象四、Class类型的对象使用场景1五、Class

Android Kotlin 高阶函数详解及其在协程中的应用小结

《AndroidKotlin高阶函数详解及其在协程中的应用小结》高阶函数是Kotlin中的一个重要特性,它能够将函数作为一等公民(First-ClassCitizen),使得代码更加简洁、灵活和可... 目录1. 引言2. 什么是高阶函数?3. 高阶函数的基础用法3.1 传递函数作为参数3.2 Lambda

Android自定义Scrollbar的两种实现方式

《Android自定义Scrollbar的两种实现方式》本文介绍两种实现自定义滚动条的方法,分别通过ItemDecoration方案和独立View方案实现滚动条定制化,文章通过代码示例讲解的非常详细,... 目录方案一:ItemDecoration实现(推荐用于RecyclerView)实现原理完整代码实现

Android App安装列表获取方法(实践方案)

《AndroidApp安装列表获取方法(实践方案)》文章介绍了Android11及以上版本获取应用列表的方案调整,包括权限配置、白名单配置和action配置三种方式,并提供了相应的Java和Kotl... 目录前言实现方案         方案概述一、 androidManifest 三种配置方式

Android WebView无法加载H5页面的常见问题和解决方法

《AndroidWebView无法加载H5页面的常见问题和解决方法》AndroidWebView是一种视图组件,使得Android应用能够显示网页内容,它基于Chromium,具备现代浏览器的许多功... 目录1. WebView 简介2. 常见问题3. 网络权限设置4. 启用 JavaScript5. D

Android如何获取当前CPU频率和占用率

《Android如何获取当前CPU频率和占用率》最近在优化App的性能,需要获取当前CPU视频频率和占用率,所以本文小编就来和大家总结一下如何在Android中获取当前CPU频率和占用率吧... 最近在优化 App 的性能,需要获取当前 CPU视频频率和占用率,通过查询资料,大致思路如下:目前没有标准的

Nginx之upstream被动式重试机制的实现

《Nginx之upstream被动式重试机制的实现》本文主要介绍了Nginx之upstream被动式重试机制的实现,可以通过proxy_next_upstream来自定义配置,具有一定的参考价值,感兴... 目录默认错误选择定义错误指令配置proxy_next_upstreamproxy_next_upst

Android开发中gradle下载缓慢的问题级解决方法

《Android开发中gradle下载缓慢的问题级解决方法》本文介绍了解决Android开发中Gradle下载缓慢问题的几种方法,本文给大家介绍的非常详细,感兴趣的朋友跟随小编一起看看吧... 目录一、网络环境优化二、Gradle版本与配置优化三、其他优化措施针对android开发中Gradle下载缓慢的问

Android 悬浮窗开发示例((动态权限请求 | 前台服务和通知 | 悬浮窗创建 )

《Android悬浮窗开发示例((动态权限请求|前台服务和通知|悬浮窗创建)》本文介绍了Android悬浮窗的实现效果,包括动态权限请求、前台服务和通知的使用,悬浮窗权限需要动态申请并引导... 目录一、悬浮窗 动态权限请求1、动态请求权限2、悬浮窗权限说明3、检查动态权限4、申请动态权限5、权限设置完毕后

Android里面的Service种类以及启动方式

《Android里面的Service种类以及启动方式》Android中的Service分为前台服务和后台服务,前台服务需要亮身份牌并显示通知,后台服务则有启动方式选择,包括startService和b... 目录一句话总结:一、Service 的两种类型:1. 前台服务(必须亮身份牌)2. 后台服务(偷偷干