首页 > 其他分享 >click事件生成

click事件生成

时间:2024-06-16 16:00:51浏览次数:5  
标签:控件 调用 生成 dispatchAttachedToWindow 事件 方法 click

click事件生成和attachInfo传递

click事件生成(onClick调用)

在Android开发中经常用到click事件监听,但其实click事件并不是地方传上来的事件,底层上报事件都是touch事件,而click事件其实是根据touch事件生成的,或者说click事件并不是一个纯粹的事件

在View的onTouchEvent方法中,在收到MotionEvent.ACTION_DOWN事件的时候有如下逻辑

这里截取了部分主要源码,这里其实主要设置了下flag,然后主要是调用了checkForLongClick(走if分支时CheckForTap也会调用checkForLongClick方法)该方法主要是发送一个延时事件,如果到时该延时事件没有取消,则会执行该事件,这就是LongClick事件的生成,稍后再总结长按事件

在收到MotionEvent.ACTION_UP事件的时候

这里截取了部分主要源码,前面removeLongPressCallback方法会移除在down事件时发送的长按事件的延时任务,而mPerformClick任务则是执行click事件

click事件

根据前面的分析,click事件主要代码如上,其调用有两种,首先post一个PerformClick任务,如果post返回false则调用performClickInternal方法,其最后的逻辑都是一致的,这里先看下PerformClick任务

显然PerformClick任务中就是调用performClickInternal方法

继续走读代码,performClickInternal主要时调用performClick方法

到performClick方法就很明朗了,这里有获取onClick监听,如果有添加onClick监听器,则这里调用其onClick方法

长按事件

长按事件和click事件相似,不过长按事件实际是在down时生成的(延时任务),不过如果up时还没执行则会取消长按事件(还有些如cancel事件等场景这里不具体讨论,只是大概介绍下流程)

根据前面介绍的情况,这里走读下一般场景下调用,如上,走checkForLongClick方法

显然这里是postDelayed一个CheckForLongPress任务,查看其run方法:

显然,CheckForLongPress任务触发时会调用performLongClick方法,继续走读代码

到这里就到到具体事件回调的地方了,在performLongClickInternal方法中,如果有设置长按事件监听器,这里即会调用其onLongClick方法

post和postDelayed

前面分析中和View代码中有多处post和postDelayed方法调用,但其并不是直接有个handle去调用,View自己有实现post和postDelayed方法

如上,其post和postDelayed方法结构相似,其都是调用的mAttachInfo的mHandler对象的post和postDelayed方法(getRunQueue的相关调用看代码只在dispatchAttachedToWindow方法中会执行,正常来说一般在界面显示的时候就会走dispatchAttachedToWindow方法,后面除非移除控件再次添加,不然基本不会 重复调用,所以getRunQueue的相关调用一般情况下基本不会走到)

mAttachInfo在下面会具体分析,其mHandler是ViewRootImpl中的ViewRootHandler内部类的一个对象(ViewRootHandler继承Handler)

attachInfo传递

View的mAttachInfo最开始是在ViewRootImpl中创建的,然后在第一次绘制的时候分发到控件树的根节点,然后依次向子节点分发

如上,在ViewRootImpl的构造方法里创建了View.AttachInfo的对象mAttachInfo

然后在ViewRootImpl的performTraversals方法中mFirst条件代码中有调用host.dispatchAttachedToWindow方法,如下

这里host即是一般控件树的根节点

然后看下View和ViewGroup的dispatchAttachedToWindow方法逻辑

在View的dispatchAttachedToWindow中首先会给当前控件的mAttachInfo变量赋值,然后有些回调等,如onAttachedToWindow调用

在ViewGroup的dispatchAttachedToWindow主要是将attachInfo传递到控件树的子节点

这里有super调用,即会走View的dispatchAttachedToWindow方法,这样attachInfo就赋值给了当前控件

然后有对mChildren和mTransientViews分别进行遍历调用,前者是一般的控件树传递,后者是临时控件的传递,其逻辑相似(临时控件用的场景比较少,而且这里逻辑相似不单独分析)

这里mChildren就是控件树中的当前控件的子节点控件数组,这里对子节点控件分别调用dispatchAttachedToWindow方法,即会将attachInfo传递给了其子控件,就这样,attachInfo就从控件树的根节点一级一级的传递到控件树所有控件

不要在onAttachedToWindow中调用bringToFront方法

之前工作有遇到个控件点击无响应的问题,最后分析是控件的mAttachInfo未赋值,而其根因是在其无响应控件同级控件的onAttachedToWindow中有调用bringToFront方法,在atttachInfo分发时改变了控件的顺序,导致有的控件并未分发到,从而导致了问题

这里简单介绍下

在前面attachInfo分发中(ViewGroup. dispatchAttachedToWindow)已经了解到其是遍历mChildren调用其子元素的dispatchAttachedToWindow方法

然后我们先看下bringToFront方法(View),其会调用其父节点控件的bringChildToFront方法

其会调用其父节点控件的bringChildToFront方法(ViewGroup)

bringChildToFront方法前面主要就是操作mChildren数组,将对应的控件先从mChildren移除,然后添加到mChildren末尾

然后回到这个问题的过程,

这里画了个简易流程图来说明,这里假设假设父控件是当前分发attachInfo的控件,其有两个子控件,子控件1在onAttachToWindow方法中调用了bringToFront方法

然后分析其分发过程:

  1. 将attachInfo赋值给父控件
  2. 遍历其子控件,先调用其第一个子控件,这里即子控件1的dispatchAttachedToWindow方法,然后会将attachInfo赋值给子控件1,然后回调其onAttachedToWindow方法,然后其调用了bringToFront方法,即会将子控件1挪到其父控件的子控件列表的末尾,即变成右图所示
  3. 继续遍历,这时调用父控件的第二个子控件,这里根据上图右图所示仍是子控件1

从上面分发过程可知,这个过程中子控件2其实并没有遍历到,也就没有被分发attahInfo,当然其也不会回调onAttachedToWindow,可能还有些其他问题,不过其mAttachInfo未赋值,根据前面的分析,其点击事件也不会响应,不会回调onClick方法

标签:控件,调用,生成,dispatchAttachedToWindow,事件,方法,click
From: https://www.cnblogs.com/luoliang13/p/18250707

相关文章

  • visible_windows生成逻辑和解析
    visible_windows生成逻辑和解析visible_windows生成逻辑在开发者选项中生成错误报告或命令行使用dumpstate,会生成一个bugreprot的压缩包,如其中包含了一些dump信息,其中海有个压缩包里面包含了一些可见窗口的控件信息,但用notepad打开却多是乱码之前工作遇到过一个显示问题只有截图、......
  • 算法人生(22):从“生成对抗网络”看“逆商提升”
    ​在图像生成与编辑、音频合成、视频生成领域里,有一个非常重要的深度学习方法——生成对抗网络(简称GANs),它是由两个神经网络组成的模型,分别为生成器(Generator)和判别器(Discriminator),这两个网络相互博弈,通过对抗学习的方式来训练,以便生成逼真的数据样本。它的大致步骤如下:初始......
  • python 如何生成原创文章
    生成原创文章是一个复杂的过程,因为它需要创造力、知识、语法和上下文理解。然而,Python可以用于辅助文章创作,例如通过生成文本、组合现有信息或根据特定模式进行内容创建。但要完全生成一个完全原创、有深度且逻辑连贯的文章,目前的技术还无法完全实现。不过,以下是一些Python可......
  • 华为余承东:全场景代码智能生成工具CodeArts snap正式发布,码力遥遥领先
    野心让人勤奋节制让人枯萎   前几天的端午节,华为发布了新一代代码智能生成工具codeartssnap。可以一键生成高效代码,精准解决技术难题,让你像技术大牛一样轻松完成业务开发。  下面来看看它是如何码力全开的。 第一个,通过注释一键生成代码如下,当你写好代码的注......
  • 拜耳推出农业生成式AI系统GenAI
    近期,拜耳公布了一项开创性的试点计划,引入了一个专业的生成式人工智能(GenAI)系统,旨在提高效率,并增强农艺师的日常工作能力。利用专有的农艺数据,拜耳利用其全球农艺师网络数百年的丰富经验,训练了一个复杂的大型语言模型(LLM)。GenAI系统代表了农业技术的重大飞跃,可以快速准确地回答与......
  • 课设--学生成绩管理系统(二)
    欢迎来到 Papicatch的博客目录......
  • 基于事件触发机制的孤岛微电网二次电压与频率协同控制仿真模型(Simulink仿真实现)
    ......
  • Oracle 性能调优 10053事件
    思维导图10053事件概述我们在查看一条SQL语句的执行计划时,只看到了CBO最终告诉我们的执行计划结果,但是我们并不知道CBO为何要这样做。特别是当执行计划明显失真时,我们特别想搞清楚为什么CBO会做出这样的一个选择,那么就可以用10053事件来分析SQL分析过程的trace文件。同100......
  • 小吴讲故事之假如我有100w(java生成pdf文档,一页A4多条数据)
    故事背景各位码农们好!我是在社会接受练习时长2年半的java练习生,大家也可以叫我小卡拉米吴!最近在项目中遇到一个需求,就是有关于pdf文件生成的,具体需求如下。到了小卡拉米吴讲故事的时间了:事情是这样的。小吴是一名普通的码农,和野原广志一样,但不是小组长,生活除了工作就是回......
  • python爬取校园集市帖子并生成词云图
    注:本篇需要python基础,json基础前言:上篇我们学习了怎么用python获取百度热搜,在这篇中,我们将进一步学习,利用python爬取校园集市帖子并生成词云图目录第一步,分析请求第二步,编写代码第三步,批量获取帖子第四步,绘制词云图灵感背景:经常在群里看见机器人转发的校园集市帖子,于是想要爬......