Android 事件分发机制

Android事件分发机制 开始的开始 当我手指触摸到手机屏幕后,给我所见即所得的触控体验,它的背后发生了什么?出于对它的好奇,就有了这篇文章。因为本人不喜欢大段大段的源码分析,所以本文尽量从设计的角度去把把事件分发机制的脉络,少贴源码是我的目标之一,虽然这么说,但当我把文章写完后最后发现依然贴了不少代码,想删减却没法减少,都是很核心的部分。本博客的主要内容如下: 事件分发的整体设计 ViewRootImpl的创建 应用层级的事件分发流程 为了后面更容易的理解事件分发机制,在介绍核心内容前,准备了一些前置知识。 前置知识:View 阅读详情

Android 事件分发机制

口诀: 3个主体6件事,3个流程负责制
  • 三个主体: Activity , ViewGroup, View
  • 六件事:dispatchTouchEvent,onInterceptTouchEvent,onTouchEvent,requestDisallowInterceptTouchEvent,onTouchListener,onClickListener
  • 三个流程: MotionEvent.ACTION_DOWN, MotionEvent.ACTION_MOVE, MotionEvent.ACTION_UP
  • 负责制:负责到底只要事处理了流程中的ACTION_DOWN的事件的主体return true,后面的整个都要交给它处理

流程图:https://www.jianshu.com/p/e99b5e8bd67b

流程图的解释请参考,参考的说明里面:https://www.jianshu.com/p/e99b5e8bd67b
这里需要注意的: 在这里插入图片描述

  • 1: activity 如果dispatchTouchEvent不是return的super 那么都会丢弃,不会再往下传递,也不会触发onTouchEvent的事件
  • 2: 执行优先级 onTouchListener >onTouchEvent>onClickListener 如果onTouchListener 的回调onTouch里面 返回的是true那么不会执行onTouchEvent
public boolean onTouchEvent(MotionEvent event) {
            
   case MotionEvent.ACTION_UP:
...
    if (!mHasPerformedLongPress && !mIgnoreNextUpEvent) {
        // This is a tap, so remove the longpress check
    removeLongPressCallback();

     // Only perform take click actions if we were in the pressed state
     if (!focusTaken) {
        // Use a Runnable and post this rather than calling
        // performClick directly. This lets other visual state
        // of the view update before click actions start.
        if (mPerformClick == null) {
            mPerformClick = new PerformClick();
        }
        if (!post(mPerformClick)) {
            performClickInternal();
        }
    }
}
    ...
}
mMyView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Log.d("kodulf","View on click listener");
            }
        });

        mMyView.setOnTouchListener(new View.OnTouchListener() {
            @Override
            public boolean onTouch(View v, MotionEvent event) {
                Log.d("kodulf","View on touch listener");
                return false;
            }
        });
执行结果:
 D/kodulf: part: =============Activity method:[-dispatchTouchEvent -] action:DOWN 
 D/kodulf: part: -- LinearLayout -- method:[- dispatchTouchEvent  -] action:DOWN 
 D/kodulf: part: -- LinearLayout -- method:[-MotionEvent -] action:DOWN 
 D/kodulf: part: -- LinearLayout -- method:[- dispatchTouchEvent  -] action:DOWN 
 D/kodulf: part: -- LinearLayout -- method:[-MotionEvent -] action:DOWN 
 D/kodulf: part: ++++ My View  method:[- dispatchTouchEvent  -] action:DOWN 
 D/kodulf: View on touch listener
 D/kodulf: part: ++++ My View  method:[-onTouchEvent -] action:DOWN 
 D/kodulf: part: =============Activity method:[-dispatchTouchEvent -] action:UP 
 D/kodulf: part: -- LinearLayout -- method:[- dispatchTouchEvent  -] action:UP 
 D/kodulf: part: -- LinearLayout -- method:[-MotionEvent -] action:UP 
 D/kodulf: part: -- LinearLayout -- method:[- dispatchTouchEvent  -] action:UP 
 D/kodulf: part: -- LinearLayout -- method:[-MotionEvent -] action:UP 
 D/kodulf: part: ++++ My View  method:[- dispatchTouchEvent  -] action:UP 
 D/kodulf: View on touch listener
 D/kodulf: part: ++++ My View  method:[-onTouchEvent -] action:UP 
 D/kodulf: View on click listener    
  • 3: requestDisallowInterceptTouchEvent 这个必须是使用getParent().requestDisallowInterceptTouchEvent. 但是它对ACTION_DOWN 是无效的,因为如果没有ACTION_DOWN传递过来的话,它怎么执行呢?

实例

1.0 事件分发的 demo

1.1 ViewPager 和 SlidingPanelLayout 的滑动冲突的解决
 @Override
    public boolean onTouchEvent(MotionEvent ev) {

        float rawX = ev.getRawX();
        int width = getWidth();
        if(rawX >=width/10)
            if(ev.getAction() == MotionEvent.ACTION_DOWN)
            getParent().requestDisallowInterceptTouchEvent(true);

        return super.onTouchEvent(ev);
    }
  • 2: 也可以自定SlidingPanelLayout 在他的事件拦截里面执行:
    @Override
    public boolean onInterceptTouchEvent(MotionEvent ev) {

        float rawX = ev.getRawX();
        int width = getWidth();
        if(rawX <width/10||rawX>(width*9)/10)
            return super.onInterceptTouchEvent(ev);
        else
            return false;
    }
  • 3: 顺便说一下:DrawerLayout 是不需要去写这个的,因为他内部嵌入了
Seurat3.0小提琴图腰围的参数 小提琴图没有有些群没有出现小提琴只有点点,是由于0值比例太多, 一个关键的参数scale = "width"导致了这种局面,应加上上述参数 ggplot(p$data,aes(ident,CD4)) + geom_violin(scale = "width", adjust =1, trim = TRUE) + geom_jitter()+ theme_bw() adjust参数可以调整腰的粗细,eg: ggplot(p$data,aes(ident,CD4)) + geom_violin(scale 阅读详情

相关推荐

绕过卡巴斯基通过RPC控制lsass注入DLL

参考国外的XPN以及3gstudent大佬的文章: https://blog.youkuaiyun.com/xiangshen1990/article/details/104872566 https://gist.github.com/xpn/93f2b75bf086baf2c388b2ddd50fb5d0 原理:正常的ssp扩展(dll)可以加载到lsass进程中去,比如kerberos验证都是通...

2ed 3524

AndroidStudio 中使用 百度地图 <四> 百度地图实现打开就显示当前位置,个人摘要

0:注册key http://lbsyun.baidu.com/apiconsole/key/create 关于如何创建SHA1 请参考:里面的AndroidStudio 中使用 百度地图 百度地图的导入和集成,个人摘要 得到key 0vuea4B0323lkNglN6Rbekbk 1:然后将百度SDK集成进去,

Kodulf的专栏 2632

ARM架构实战:在鲲鹏920服务器上用Debian12部署PVE虚拟化平台

本文详细介绍了在基于ARM架构的华为鲲鹏920服务器上,以Debian 12为底层系统,部署Proxmox VE(PVE)虚拟化平台的完整实战流程。文章重点解析了ARM64架构下PVE软件源的配置、内核安装的注意事项、部署后网络与存储的调优,并提供了针对ARM虚拟化环境的性能优化建议,为在国产化硬件上构建稳定高效的虚拟化环境提供了宝贵经验。

efc12345678的博客 780

object 类的set和get方法,点语法 和 属性生成器

首先创建一个cocoa class ,命名为Person, Person.h: // // Person.h // SetAndGet // // Created by 千 on 16/7/27. // Copyright © 2016年 kodulf. All rights reserved. // #import @interface Person : NSObject {

Kodulf的专栏 2462

CDO批量处理nc文件:5分钟搞定CMIP6数据双线性插值(附完整代码)

本文详细介绍了如何使用CDO工具链中的`remapbil`命令,快速实现CMIP6数据的批量双线性插值处理。通过环境配置、核心操作步骤、高级优化技巧及典型报错解决方案,帮助科研人员高效处理大规模nc文件,显著提升气象数据处理效率。

weixin_29267307的博客 292

stc8g1k08硬件iic读取aht20温湿度及0.91寸oled显示

使用stc8g1k08读取aht20温湿度及0.91寸oled显示。

qq_61688416的博客 2771

android 中的事件分发和事件拦截

old 代码:事件分发和事件拦截 good :https://www.jianshu.com/p/e99b5e8bd67b new :https://github.com/kodulf/EventDispatchTestDemo 事件分发:dispathTouchEvent 1. 功能:从当前容器向自己内部的子容器/控件,传递触摸事件; 2. 特点:在传递的时候,会...

Kodulf的专栏 1855

DICOM标准:DICOM医学影像中的覆盖层(Overlay)概念详解

DICOM标准:深入详解DICOM医学影像中的覆盖层(Overlay)

编程技术探索者,分享C/C++、C#、Java、数据库等开发经验,聚焦实战技巧与AI兴趣,助力编程爱好者成长。 1562

安卓-Android事件分发机制详解

链接: 原帖跳转 如何提升安卓水平?安卓开发者必须了解的事件分发机制。 最全面、最易懂的形式来讲解Android事件分发机制。 0. 前言 鉴于安卓分发机制较为复杂,故分为多个层次进行讲解,分别为基础篇、实践篇与高级篇。 (一)基础篇:从基本概念入手,介绍了分发机制中的核心方法,通过分析其核心逻辑,总结其事件分发机制。 (二)实践篇:该篇设计了简单与复杂的两个demo样例,从现象与应用的角度去讲解分发机制的核心内容,帮助读者从另一个角度理解事件分发机制。 (三)高级篇:从源码角度去分析分发机

ruiruiddd的博客 841

Python蓝色跳动的爱心(完整代码)

Python语言实现蓝色跳动的爱心的完整代码。 代码分析 这段代码使用了 库来创建一个动态的爱心图案,并在屏幕上显示带有动态效果的“我爱你”字样。以下是对这段代码的详细分析: 用于创建图形用户界面(GUI)。 用于生成随机数,主要用于控制爱心图案的扩散效果。 中的 , , , 用于数学计算,生成爱心形状和扩散效果。 包含了 等常量,用于控制控件的对齐方式。 2. 全局变量定义 , : 定义画布的大小。 , : 爱心的中心坐标。 : 用于定义爱心形状的缩放

AIGC 1920

使用MATLAB进行灰色预测 GM(1,1)

使用MATLAB进行灰色预测 GM(1,1)

Hou_____的博客 998

Android ——事件分发机制

用户在使用app时,会经常频繁的触摸屏幕,点击页面交互,打开需要的功能。用户触摸点击的动作,就涉及到app中相关UI的触摸和点击事件。事件在UI中传递和处理的过程,就是事件分发流程。发生一次点击事件时,事件会按照Activity->ViewGroup->View的顺序,进行事件传递。

qq_45730283的博客 2220

YOLOv12涨点优化:自研检测头 | 独家创新(Partial_C_v12Detect)检测头结构创新,实现涨点

现有12Detect进行二次创新,提升检测精度,独家创新(Partial_C_12Detect)检测头结构创新,适合科研创新度十足,强烈推荐

①答疑群聊服务;②YOLO大模型知识问答系统;③计算机视觉论文生成智能体; 633

【Android】事件分发机制

从上表可以看到 Activity和 View都是没有事件拦截的,这是因为:Activity 作为原始的事件分发者,如果 Activity 拦截了事件会导致整个屏幕都无法响应事件,这肯定不是我们想要的效果。View作为事件传递的最末端,要么消费掉事件,要么不处理进行回传,根本没必要进行事件拦截。

2303_79296612的博客 1726

Data-Structures-and-Algorithm-Analysis-in-Java.pdf

作者: Weiss, Mark A. 出版社: Addison Wesley Data Structures and Algorithm Analysis in Java is an “advanced algorithms” book that fits between traditional CS2 and Algorithms Analysis courses. In the old ACM Curriculum Guidelines, this course was known as CS7. This text is for readers who want to learn good programming and algorithm analysis skills simultaneously so that they can develop such programs with the maximum amo...

汉书HE8,好用的汇编代码编写工具

汉书HE8,好用的汇编代码编写工具早期编写汇编代码所用功能强大

安卓事件分发机制

此方法用来处理事件的分发,当事件传递给当前View时,首先就是通过调用此方法进行传递的,如果当前View所包含的子View的dispatchTouchEvent方法或者当前View的onTouchEvent方法处理了事件,通常返回true,表示事件已消费,如果没有处理则返回false。用来处理事件,如果事件被消费了,通常返回true,否则返回false,并再同一个事件序列中,当前View不会再接受到事件。事件是指用户与应用程序交互时产生的动作或操作,如触摸事件、手势事件、按键事件。

weixin_45911701的博客 1005

Devexpress16.2.6破解工具

Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具

安卓触摸事件分发机制分析

🎯 一句话总结:触摸事件(TouchEvent)会从Activity层开始,按从外到内的方式传递给每一个 ViewGroup/View,直到某个 View消费(consume)它,事件传递就会停止。📌 事件分发三个关键方法方法名所在类作用说明所有 View/ViewGroup事件分发入口,决定是否继续向下传递仅 ViewGroup是否拦截事件,阻止传递给子 View所有 View/ViewGroup事件的最终处理者(消费者)DecorView是一个应用窗口的根容器,它本质上是一个。

WriteBug001的博客 971

Statistics and Machine Learning Toolbox

Statistics and Machine Learning Toolbox(带书签),MATLAB统计学习工具

安卓入门三十四 事件分发机制原理

这种设计是非常精巧的,上层View既可以直接拦截该事件,自己处理,也可以先询问(分发给)子View,如果子View需要就交给子View处理,如果子View不需要还能继续交给上层View处理。如下图,View是一层一层嵌套的,当手指点击View1的时候,下面的ViewGroupA、RootView等也是能够响应的,为了确定到底应该是哪个View处理这次点击事件,就需要事件分发机制来帮忙。前面我们了解到了我们的View是树形结构的,基于这样的结构,我们的事件可以进行有序的分发。

weixin_52735932的博客 931

安卓view事件分发机制

安卓view事件分发机制

似霰的博客 981

Android View的事件分发机制

Android View的事件分发机制

m0_74448051的博客 1153

带你深入了解Android的事件分发机制

事件拦截(Event Intercept):事件拦截是指在事件分发过程中,某个ViewGroup可以拦截事件的传递,阻止它传递给子View。Android的事件分发机制是指在Android系统中,如何将用户的触摸事件、按键事件等传递给正确的View进行处理的一套机制。值得注意的是,在编写代码时,需要仔细理解每个方法的作用和调用时机,确保事件的正确传递和处理,避免潜在的问题和冲突。通过重写以上方法,你可以根据自己的需求来实现事件的分发和处理逻辑,例如拦截特定的手势,定制化事件的响应等。

Dakaring的专栏 2681

Android 事件分发机制深度解析

答:Activity -> Window -> DecorView -> ViewGroup -> View。内部拦截法:子View调用requestDisallowInterceptTouchEvent():消费ACTION_DOWN的View将接收整个事件序列。后续事件:若未拦截DOWN,仍可拦截MOVE/UP。:View应在DOWN时初始化触摸状态。:一旦拦截,整个事件序列不再检查拦截。:GONE状态的View不参与分发。:后添加的子View优先(可通过。:仅分发到触摸区域内的子View。

qq_45906596的博客 1601

安卓中的事件分发机制源码解析

安卓中的事件分发机制主要涉及到两类控件,一类是容器类控件ViewGroup,如常用的布局控件,另一类是显示类控件,即该控件中不能用来容纳其它控件,它只能用来显示一些资源类容,如Button,ImageView等控件。暂且称前一类控件为ViewGroup类控件(尽管ViewGroup本身也是一个View),后者为View类控件。

(* ̄︶ ̄) 8万+

安卓View—事件分发机制(二)

安卓View—事件分发机制 文章目录安卓View—事件分发机制一、基础知识1.事件分发是什么2.点击事件的传递规则3.事件分发的顺序二、事件分发源码分析1.Activity对点击事件的分发过程2.ViewGroup对点击事件的分发过程3.View对点击事件的分发过程三、事件分发总结 一、基础知识 1.事件分发是什么 事件分发就是对MotionEvent事件的分发过程,即当一个MotionEvent...

睡客的博客 1752
上一篇: 转 Android 异常及性能优化系列之 Systrace
下一篇: 周志华老师对于研究生入学的要求
千雅爸爸
博客等级 码龄18年 292粉丝 639原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值