Android触摸事件-深度剖析

Android开发避坑:ImageButton点击事件和触摸事件冲突了怎么办? 本文深入解析Android开发中ImageButton点击事件与触摸事件冲突的问题,提供多种解决方案包括合理使用返回值、自定义View处理以及状态机模式。通过剖析Android事件分发机制,帮助开发者有效解决交互冲突,提升应用用户体验。 阅读详情

事件分发


面试官: 描述一下你知道的点击事件分发流程
我: 直接从Java层讲起, 还是从硬件层?
Java层回答
  • 当用户点击屏幕时, 将产生事件序列, 包括DOWN、MOVE、UP、CANCEL
  • 事件分发的本质, 其实就是将事件列传递到某个具体View的过程
  • 事件分发主要由三个方法协作完成: dispatchTouchEvent、onInterceptTouchEvent、onTouchEvent
  • dispatchTouchEvent 用于分发点击事件
  • onInterceptTouchEvent 在 dispatchTouchEvent 内部调用, 是 ViewGroup 独有, 用于 ViewGroup 判断是否拦截事件
  • onTouchEvent 在 dispatchTouchEvent 内部调用, 用于处理事件序列
  • 如果想要聊清楚事件分发, 就需要从头到尾梳理, 这里面有几个关键点
    • Activity 事件分发机制
    • ViewGroup 事件分发机制
    • View 事件分发机制
  • 用户点击屏幕 (ACTION_DOWN)
    • ViewRootImpl
    • ↓ DecorView
    • ↓ Activity.dispatchTouchEvent
    • ↓ PhoneWindow.superDispatchTouchEvent
    • ↓ DecorView.superDispatchTouchEvent
    • ↓ 根ViewGroup.dispatchTouchEvent
      • return true
        • 事件被消费, Activity.dispatchTouchEvent 返回 true, 事件分发结束
      • return false
        • 事件未消费, 执行 Activity.onTouchEvent
  • ViewGroup.dispatchTouchEvent
    • ↓ 条件判断: disallowIntercept || !onInterceptTouchEvent()
      • /* disallowIntercept默认false, 可经 ViewGroup.requestDisallowInterceptTouchEvent 设置为true, 用于强制关停ViewGroup的onInterceptTouchEvent的事件拦截控制 */
      • true -> ViewGroup 不拦截事件
        • ↓ 倒序遍历子View
          • ↓ 判断当前遍历View是否正在点击
            • ↓ 执行并判断某子View.dispatchTouchEvent
              • true: 该子View消费了点击事件, mFirstTouchTarget 记录为该View, 方便相同事件序列的事件快速被消费, 而不需要再次遍历
              • false, 该子View不消费点击事件
        • 子View们不消费事件, 执行ViewGroup之父类View的dispatchTouchEvent
      • false -> 拦截事件
        • 会执行ViewGroup.super.dispatchTouchEvent
          • 调用父View.dispatchTouchEvent
            • 先检查 OnTouchListener,
              • 返回 true,事件消费, 分发流程结束
              • 返回 false
                • 调用 onTouchEvent
                  • 处理在 ACTION_UP 时触发点击 performClick
                  • performClick 内部触发 OnClickListener
  • View.dispatchTouchEvent
    • 是否外部注册了 onTouch 事件监听 (View.registerOnTouchListener())
      • 是
        • onTouch 返回 true
          • View.dispatchTouchEvent 返回true, 消费该事件
            • 结束
        • onTouch 返回 false
          • 往下走, 执行 View.onTouchEvent
      • 否
        • 执行 View.onTouchEvent
          • 如果是抬起事件
            • 执行 performClick
              • 是否注册点击事件
                • 是 -> 回调 onClick
                • 否 -> 结束
硬件层回答
  • 用户执行按下、滑动行为. 硬件层产生按下、滑动事件
  • 内核层
  • 事件到达 Native 层, InputDispatcher 通过 InputChannel (Socket对的服务端) 将事件发送到应用进程的Native缓存
  • 主线程Looper执行到MessageQueue.next.nativePollOnce, 会通过 NativeInputEventReceiver 读取 Socket 数据
  • 如果是Down事件
特快直达, 画面跟手、丝滑(防掉帧)
  • 直接回调给 Java 层的 ViewRootImpl.WindleInputEventReceiver.onInputEvent
  • 执行enqueueInputEvent, 传入的 “立即执行” 参数为true
    • 这使得接下来执行 doProcessInputEvents , 他不会发送异步消息, 更不会等待, 而是直接冲进分发流程
  • 如果是Move事件
批处理 + 异步消息, 追求渲染流畅性(对齐 VSYNC 分发)
  • 不直接回调给 Java 层的 ViewRootImpl.WindleInputEventReceiver.onInputEvent, 而是将事件合并, 然后回调给ViewRootImpl.WindleInputEventReceiver.onBatchedInputEventPending
    • 这个方法会调用 ViewRootImpl.scheduleConsumeBatchedInput, 发送一个消费Batch队列的任务(ConsumeBatchedInputRunnable)消息, type是CALLBACK_INPUT
  • 当 VSYNC 信号到来, 底层唤醒主线程, Choreographer 会严格按下面优先级调度
    • CALLBACK_INPUT: 处理 ACTION_MOVE 的分发、处理手势计算
    • CALLBACK_ANIMATION: 执行 ObjectAnimator、ValueAnimator 的数值更新。
    • CALLBACK_INERTS_ANIMATION: 处理软键盘、状态栏弹出过程中的位移动画。
    • CALLBACK_TRACERSAL: 执行 ViewRootImpl 的 Measure、Layout、Draw。
    • CALLBACK_COMMIT: 最后的清理工作(现在版本较少使用)
  • Choreographer.CALLBACK_INPUT 被触发, 会执行 ViewRootImpl.ConsumeBatchedInputRunnable.run,
    • 这里面先执行 consumeBatchedInputEvents, 将 Native 中的 Batch队列 捞出来放进Java层的 mPendingInputEventHead 链表中
    • 然后就会执行到 doProcessInputEvents 遍历链表中的事件进行分发, 开始 DecorView -> Activity -> PhoneWindow -> DecorView -> ViewGroup -> View 这个大家熟悉的事件分发流程了
  • 总结:
    • 流程:
      • 硬件触摸信号
      • (Linux kernel) InputChannel
      • (Native) InputDispatcher
      • (Native) Batch 队列
      • (Java) ViewRootImpl.WindleInputEventReceiver.onBatchedInputEventPending
      • (硬件) VSYNC
      • (Java) Choreographer.CALLBACK_INPUT
      • (Java) ViewRootImpl.ConsumeBatchedInputRunnable
      • Batch 队列 -> 事件链表
      • doProcessInputEvents
      • deliverInputEvent
      • Java 层标准事件分发流程
    • 为什么这么设计 MOVE 事件分发
      • 解决 “生产” 与 “消费” 速率不匹配问题
        • 现在主流手机采样率(如 240Hz)远高于刷新率(如 60Hz)。这意味着硬件每秒产生 240 个 MOVE 事件,但显示器每秒只能消费(渲染)60 帧。
        • 如果每一条 MOVE 都触发一次分发和 View 树重绘,主线程会进行 180 次无效的计算。因为即便 View 状态更新了,屏幕由于没到 VSYNC 信号也不会刷新,用户根本看不见中间的变化。
        • 这种“强行刷新”会导致主线程消息堆积。240 个事件会产生 240 个高优先级的任务,将真正重要的“渲染任务”挤到后面。一旦主线程处理这些冗余事件的时间超过 16.6ms,就会错过 VSYNC 信号,产生明显的掉帧(Jank)
        • Android 引入 批处理 + VSYNC + Choreographer, 将多个MOVE事件在下一个VSYNC时刻中处理, 实现极致的流程性
          • 这种设计把事件处理从‘事件驱动’转变成了‘时钟驱动’(VSYNC 驱动)。不再被动地被上百个滑动信号牵着走,而是主动地按照显示的节奏去提取数据。这才是解决滑动卡顿的终极方案。

总结
doProcessInputEvents 之后的分发流程

面试题
  • 面试官: View注册了onTouch监听、onClick监听, onTouch中返回false, onClick会执行吗?
    • 我: 会, onTouch返回false, 会执行View.onTouchEvent, 内部逻辑会执行View.performClick, 然后检查是否注册点击监听, 有的话会回调onClick
    • 面试官: 那返回true呢?
      • 我: 不会, onTouch返回true, View.dispatchTouchEvent就会直接返回true, 这样就不会再执行View.onTouchEvent了, 也就不会回调onClick
  • 面试官: DOWN、MOVE、UP 在流程中怎么处理的?
    • 我:
      • DOWN 是一次事件序列的起始点, 中间会有0或多次的MOVE, 事件序列最终结束于UP或CANCEL
      • DOWN、UP 是快速执行的, 不存在批处理 和 异步消息
      • MOVE 为追求稳定, 需要 VSYNC + Choreographer 组合起来, 对MOVE事件进行批处理 + 异步消息, 处理采样率和刷新率不一致的问题,
  • 面试官: 当某子View消费了Down事件, 后续ViewGroup的Move、Up会怎么分发?
    • 我:
      • 在父ViewGroup明确不消费后续Move、Up的条件下, 某许的Move、Up都会交给该子View处理
        • 因为如果某个子View消费了DOWN事件, 会被记为mFirstTouchTarget, 在父ViewGroup.onInterceptTouchEvent不拦截MOVE、UP的条件下, 后续的MOVE、UP都会交给该子View消费
  • 面试官: 既如此, 那父ViewGroup拦截了Move, 消费Down事件的子View会怎样?
    • 我: 消费Down事件的子View, 会收到Cancel的事件, 其他无关子View, 不会收到任何事件
  • 面试官: 聊一聊这个mFirstTouchTarget字段
    • 当ViewGroup.dispatchOnTouchEvent收到Down事件
      • 会将mFirstTouchTarget置为null
      • 判断ViewGroup是否拦截
        • 拦截: mFirstTouchTarget会一直为null, 事件最终都由该ViewGroup之父类View的dispatchTouchEvent处理, 最终消不消费, 还是由onTouchEvent决定
        • 不拦截: 倒序到消费的子View, 找不到, 事件还由ViewGroup处理, 找得到, mFirstTouchTarget置为该子View的包装对象, 事件也给该子View处理
      • 收到后续的Move、Up事件
        • 检查ViewGroup是否拦截
          • 不拦截, 交给mFirstTouchTarget处理
          • 拦截, ViewGroup自己处理, mFirstTouchTarget收到Cancel事件
  • 面试官: 聊一下从硬件层到软件层的点击事件传递
硬件层 -> Linux内核 -> Android系统服务 -> 应用进程(跨进程接收 -> 主线程接收 -> 视图树分发 -> 事件消费 -> 反馈)
  • 我
    • 从硬件层, 到框架层, 再到应用层描述一下
      • 硬件:
        • 用户触摸屏幕, 电容屏触发控制器产生电信号, 触发硬件中断
      • Linux 内核:
        • “中断服务程序” 读取原始坐标数据, 通过 “输入子系统” 将其标准化为 input_event , 并写入 /dev/input/eventX 设备节点
      • Android系统服务:
        • EventHub 通过 epoll 监听 /dev/input/ 下的设备文件, 读取原始的RawEvent
        • InputReader 在一个16ms间隔的loop中, 从EventHub中得到RawEvent并加工
          • 包括: 坐标校准、去抖、多点触摸跟踪、手势初步识别(单击长按)
          • 数据封装成 NotifyMotionArgs 后, 调用InputDispatcher.notifyMotion进行事件分发
        • InputDispatcher 分发事件
          • 想WMS查找触摸点最顶点可触摸的窗口
          • 通过InputChannel(一对Socket的Server端)将事件发到目标应用进程
            • 如果是ACTION_DOWN, 会同时启动一个5s的ANR计时器
      • 应用进程:
        • 跨进程接收: 应用进程的 ViewRootImpl 通过 InputEventReceiver 监听 InputChannel(一对Socket的Client端)
        • 主线程接收❌❌❌: ViewRootImpl 将事件包装成 MotionEvent 对象, 并通过 Handler 发送给主线程
          • DOWN 是直接执行的
          • MOVE 才会被(批处理 + 异步消息)发送给主线程Handler, 在下一个VSYNC优先执行
      • 应用视图树分发:
        • ViewRootImpl 将事件传递给根视图 DecorView.dispatchTouchEvent
        • DecorView 将事件传递给 Activity.dispatchTouchEvent
        • Activity 将事件传递给 PhoneWindow.dispatchTouchEvent
        • PhoneWindow 再将事件传回给 DecorView
          • 为什么费劲把事件传给Activity
            • 为了让 Activity 拥有事件的优先处理机会
        • 从 DecorView(一个FrameLayout) 开始, 就进入了标准的 ViewGroup 事件分发流程了
          • 上面已经说过了, 这里不再赘述
      • 事件消费与反馈:
        • 事件消费:
          • 最终消费的 View.dispatchTouchEvent 会返回true, 事件记为被消费, 分发流程结束
          • 如果找不到消费该事件的 View, 事件记为未被消费, 分发流程结束
        • 反馈
          • ViewRootImpl 通过 finishInputEvent(handled:Boolean) 向 InputDispatcher 发送结束结束信号
            • InputDispatcher 会停止该事件的 ANR 计时
          • 如果ACTION_DOWN不消费, 那接下来的整个事件序列会怎样?
            • 基于 “指责分离原则” , InputDispatcher 依旧会给应用进程的 ViewRootImpl 发送事件, 但是去到ViewGroup.dispatchTouchEvent 后会执行“快速失败”流程, 即直接走mFirstTouchTarget==null的路径, 直接执行 ViewGroup 父类 View 的dispatchTouchEvent
  • 面试官: 为什么是 16 ms
    • 我: 60 HZ 是每秒刷新60次
      • 毫秒/帧 = 1000 / 60 = 16ms
  • 面试官: ViewRootImpl 中的 InputEventReceiver 和 Choreographer 如何协同?同步屏障(SyncBarrier)在事件处理中起什么作用?
    • 我
      • 针对ACTION_DOWN, 是快速直达的, 立即响应, 在主线程Looper执行到MessageQueue.next时, 通过NativeInputEventReceiver拿到DOWN事件回调给ViewRootIMpl.WindowInputEventReceiver.onInputEvent, 这个方法最后会直接冲进事件分发流程, 执行DecorView往后的dispatchTouchEvent
      • 针对ACTION_MOVE, 因为存在屏幕采样率和屏幕刷新率不一致的问题, 因此更注重稳健性, 不允许一次采样就刷新一次屏幕的 “事件驱动” 机制, 而是引入VSYNC + Choreographer这种 “时间驱动”机制, 将一次次的MOVE事件择机打包, 在VSYNC触发时由Choreopher协调MOVE事件包怎么执行
      • MOVE跟DOWN事件不一样, 不一直接执行, 而是会择机将一次次的MOVE采样打包, 并将处理任务当成异步任务发送到主线程Handler, 在VSYNC信号来临时, 由 Choreograher 协调执行, 当MessageQueue中存在同步屏障, 会往后遍历最近的异步消息, 这里同步屏障的作用就是为了MOVE事件快点处理
  • 面试官: 为什么 View.post 时才能拿到View的宽高?
    • 我: 因为View.post发送的Message是在TRAVERSAL的Message后面执行的, TRAVERSAL进行了measure\layout\draw
  • 面试官: ViewRootImpl.WindleInputEventReceiver.onInputEvent 和 onBatchedInputEventPending 分别用于处理什么事件?
    • onInputEvent
      • 处理的即时响应的事件
        • ACTION_MOVE
        • ACTION_UP
        • KeyEvent: 返回键、音量键等物理按钮输入
    • onBatchedInputEventPending
      • 处理的连续高频的事件
        • ACTION_MOVE
YOLOv8改进策略【Neck】| BiFPN:双向特征金字塔网络-跨尺度连接和加权特征融合 可扩展的高效物体检测BiFPN(加权双向特征金字塔网络) 阅读详情

相关推荐

遥感大模型之Prithvi的关键技术解读

Prithvi系列模型开创了遥感领域基础模型新范式,通过海量多源时空数据(HLS和SAR)与Vision Transformer架构的深度融合,采用掩码自编码器进行自监督预训练,实现了强大的地球观测表征能力。该技术体系突破传统方法在全局建模、多模态融合和时空分析上的局限,仅需少量标注数据即可在土地分类、灾害监测等任务上取得优异表现。从初代3亿参数到Prithvi-EO-2.0的10亿参数升级,展现了模型可扩展性,为构建地球数字孪生智能基座奠定基础。

panshengwu的博客 866

Android 5.1触摸事件的传递机制深度剖析(上)

非原创,转自blog.waynell.com,转载请注明原出处 在Android的View系统中,TouchEvent消息的传递是非常重要的,只有深入TouchEvent消息的传递机制才能更好的理解一些View组件的原理和编写自定义View控件。本文基于Android 5.1源码进行分析。Android系统的消息处理过程,大致可以如下触摸消息 ---> 消息处理前端 ---> 窗口管理系统 --->

ywj2167917的专栏 2920

Sparse4Dv3 代码复现

打包数据集的元信息和标签,并生成所需的.pkl文件。最后还输出了很多跟踪相关的东西...然后通过K-means生成锚点。编译可变形聚合CUDA算子。安装motmetrics。

m0_60857098的博客 4487

Android View 触摸事件分发机制

本文深入解析了Android View触摸事件分发机制.

wxz的博客 480

微信聊天记录数据库解密实战:从WCDB到sqlcipher4的关键步骤解析

本文详细解析了微信桌面版聊天记录数据库的解密实战过程。通过逆向分析,定位了微信从WCDB框架到sqlcipher4加密的关键步骤,并成功提取了数据库密钥。文章重点介绍了如何通过动态调试、字符串定位等方法,追踪并验证sqlcipher4的加密密钥,最终实现对加密数据库文件的解密操作,为安全研究和数据恢复提供了技术参考。

weixin_29322553的博客 1071

信号完整性仿真SI之Cadence Sigrity SPEED2000_眼图仿真(四)

今天给大家分享一个仿真的操作流程,是关于Cadence Sigrity SPEED2000的时域波形仿真和眼图仿真。我们会经常看见硬件工程师调试示波器上的一些信号的波形变化,其实这些也可以通过仿真电路的搭建来做出投板前的仿真,来优化走线,以减少版本的迭代次数。如果要和实际的信号保持一致,就要求仿真设置的参数和实际的参数保持一致,这也是仿真的重点和难点。下面先让我们了解一下Cadence Sigrity SPEED2000时域仿真的操作流程: 1.仿真模式选择与文件导入 选择Cadence Sigrity下的

刘小同学的博客 1万+

Android自定义View深度剖析:从入门到精通

init();@Override@Override// 绘制背景圆环// 绘制进度return;i++) {理解View的生命周期和测量规则掌握Canvas的绘制方法正确处理触摸事件注意性能优化做好状态保存通过合理的设计和优化,可以创建出性能优秀、体验良好的自定义View。

疯狂假前端的博客 730

OpenClaw + Ollama 本地大模型部署教程:彻底告别Token焦虑

OpenClaw + Ollama 本地大模型部署教程:彻底告别Token焦虑

leaning_java的博客 1228

Android弹性动画实现原理:ElasticViews源码深度剖析

ElasticViews是一个专为Android开发者设计的弹性触摸效果实现库,通过简单的API即可为按钮、卡片等视图添加自然流畅的弹性反馈动画。本文将深入剖析ElasticViews的核心实现原理,帮助开发者理解弹性动画的工作机制并掌握其使用方法。 ## 核心组件解析:ElasticAnimation类 ElasticViews的核心动画逻辑封装在`ElasticAnimation`类中,该

gitblog_00631的博客 239

affymatrix探针转换 | GPL5175探针对应的基因转换

一般情况下,有一些比较成熟的对应平台的注释数据集的R包。但是这个注释平台,我在Bioconductor上找了一圈都没有找到。只能通过最原始也最可靠的方法,从GEO数据集上去下载这部分的注释文件。以下展示全过程。 我要检查的数据平台是:GPL5157。 数据集的注释集链接为:https://www.ncbi.nlm.nih.gov/geo/query/acc.cgi?acc=GPL5175 这个注释数据集比较难弄的地方在于,它的基因集注释的不太好。没有比较直接的可供提取的genesample的信息;在ge.

weixin_40640700的博客 7124

ubuntu安装英伟达显卡驱动后wifi消失解决方法

ubuntu安装英伟达显卡驱动后(比如4090和3090等),会把wifi和蓝牙驱动去除,导致wifi无法连接。需要重新下载驱动安装。

人工智能(AI)技术,大模型技术,深度学习,机器学习,计算机视觉,AI工具实践应用等分享 3903

FlowingDrawer核心组件深度解析:ElasticDrawer与FlowingMenuLayout

FlowingDrawer是一款功能强大的Android侧滑抽屉组件,以其流畅的动画效果和弹性交互体验而闻名。作为Android开发中提升用户体验的重要工具,FlowingDrawer通过ElasticDrawer和FlowingMenuLayout这两个核心组件实现了惊艳的视觉效果。本文将深入解析这两个核心组件的设计原理、实现机制和最佳实践,帮助开发者更好地理解和应用这一优秀的开源库。 ##

gitblog_00931的博客 668

Codex 的 AGENTS.md 到底怎么写?前端、后端两套实战模板,照抄就能用

文件名是大写AGENTS.md,放在项目根目录构建、测试、类型检查命令都是可直接复制执行的只写了 Agent 从代码里推断不出来的约定红线规则用了明确的否定句式(禁止/不要/Never)标注了自动生成目录和禁止修改的模块写清了交付要求(改动清单 + 验证命令 + 风险说明)没有任何密钥、密码、连接串整体一页能看完,核心要点 10 条以内每一条都能通过"删掉会不会更容易犯错"的测试一份短小精准的 AGENTS.md,比一份充斥模糊规则的长文件有用得多。

篮球界最会写bug的人;程序猿中打球最菜的人。 613

Swipeable-Cards源码探秘:卡片滑动机制与手势处理原理

Swipeable-Cards是一个原生Android库,提供类似Tinder的卡片滑动效果。通过该库,开发者可以轻松实现带有动画效果的卡片展示、左右滑动(喜欢/不喜欢)功能以及不同的排序机制。本文将深入解析其核心实现原理,帮助开发者理解卡片滑动背后的技术细节。 ## 核心组件:CardContainer的设计与实现 卡片滑动功能的核心实现位于`CardContainer`类(路径:AndTi

gitblog_00102的博客 433

VC中sqlite的使用

在VC中对sqlite的使用,实现数据库大批数据的快速插入,读取数据库中的数据在ListCtrl中显示

IEM模型,地表粗糙度模拟

利用微波反演土壤水分时候,利用IEM模型可以实现对随机地表的模拟

QtScrcpy手势操作技术解密:从鼠标映射到多指触控的完整实现

Android投屏控制软件QtScrcpy的手势操作系统是其核心交互特性之一,让开发者能够通过电脑鼠标和键盘精准模拟手机触摸操作。本文将深入解析QtScrcpy的手势实现原理,从基础的点击映射到高级的双指缩放,带你了解这一Android投屏软件背后的技术细节。 ## 手势操作的技术基础 QtScrcpy的手势操作基于事件映射机制,核心逻辑位于[QtScrcpy/ui/videoform.cpp

gitblog_00978的博客 195

Camera2Demo

在Camera2 的基础上进行封装,使得Camera2一堆初始化逻辑与Activity分离,降低耦合度,完成预览拍照并保存的操作

PinchImageView手势原理深度剖析:从触摸事件到矩阵变换的完整指南

PinchImageView是一款体验极佳的Android图片手势控件,能够让开发者轻松实现图片的缩放、平移等手势操作。本文将深入解析其内部工作原理,从触摸事件的处理到矩阵变换的实现,帮助开发者全面理解这一强大控件的运作机制。 ## 一、核心功能与应用场景 PinchImageView作为一款专业的Android图片手势控件,提供了丰富的交互功能,包括: - 双指缩放:支持图片的放大缩小操作

gitblog_00806的博客 1006

WINCC7.3破解文件

WINCC7.3硬件够破解文件,有需要的下载!WINCC7.3硬件够破解文件,有需要的下载!

深度剖析:Android NestedScrollView 惯性滑动原理大揭秘

是 Android 支持库中提供的一个可滚动的视图容器,它继承自,因此可以包含一个子视图,并允许用户通过滚动操作查看超出屏幕范围的内容。与普通的ScrollView不同,支持嵌套滚动机制,这意味着它可以与其他支持嵌套滚动的视图(如)协同工作,实现更复杂的滚动效果。通过对惯性滑动原理的深入分析,我们了解到其实现过程涉及多个关键步骤和组件。触摸事件的处理是触发惯性滑动的起点,通过跟踪手指滑动速度,当速度超过阈值时触发fling方法。fling方法借助Scroller类计算滚动的轨迹和距离,Scroller。

Android开发领域创作者 1863

揭秘 Android ListView:从源码深度剖析其使用原理

ListView 是 Android 中的一个视图组件,继承自 AbsListView,它是一个可滚动的列表视图,用于展示大量的数据项。ListView 采用了适配器模式,通过适配器(Adapter)将数据与视图进行绑定,使得数据的展示和管理更加灵活。适配器负责提供数据项的视图,ListView 则负责将这些视图排列并显示出来。适配器是 ListView 的核心组件之一,它负责将数据与视图进行绑定。ListView 通过适配器获取数据项的视图,并将其显示在列表中。

Android开发领域创作者 819

深度剖析:Android View 滑动原理大揭秘

列表滚动:在ListView等列表控件中,用户可以通过滑动来浏览列表中的内容。页面切换:在ViewPager中,用户可以通过左右滑动来切换不同的页面。侧滑菜单:通过滑动屏幕边缘,可以显示或隐藏侧滑菜单。图片缩放和拖动:用户可以通过双指缩放和单指拖动来操作图片。本文从源码级别深入分析了 Android View 的滑动原理,涵盖了通过scrollTo和scrollBy方法、动画、改变布局参数和触摸事件处理等多种实现滑动的方式,以及滑动冲突的处理和滑动性能优化等方面。通过scrollTo和。

Android开发领域创作者 1104

揭秘 Android NestedScrollView 滑动原理:源码深度剖析

通过对 Android滑动原理的深入源码分析,我们全面了解了其滑动相关的各个方面。从基本的继承关系和接口实现来看,继承自并实现了和接口,这为其具备强大的嵌套滚动能力奠定了基础。在初始化和布局过程中,构造函数完成了滚动条、嵌套滚动和滚动监听器等的初始化,onMeasure和onLayout方法分别负责测量和布局子视图,并处理滚动范围、滚动位置和滚动条的显示。触摸事件处理是滑动实现的关键环节,方法根据嵌套滚动的启用情况选择不同的处理路径,通过scrollBy和scrollTo方法实现实际的滚动操作。

Android开发领域创作者 1212

深度剖析:Android BottomSheet 使用原理大揭秘

BottomSheet 是 Android Design Support Library 中的一个组件,它允许用户从屏幕底部向上滑动显示一个视图,这个视图可以包含各种控件,如按钮、列表等。BottomSheet 有两种主要的使用方式:BottomSheetDialog 和 BottomSheetBehavior。定义了多种状态,包括拖动状态、 settling 状态(正在滚动到目标位置)、展开状态、折叠状态、隐藏状态和半展开状态。/*** 当 BottomSheet 滑动时调用。

Android开发领域创作者 1161

揭秘 Android View 位移原理:源码级深度剖析

界面切换动画:当用户切换不同的界面时,通过位移效果可以实现平滑的过渡,提升用户体验。比如从一个主界面滑动到一个详情界面。交互反馈:当用户点击一个按钮或者进行其他操作时,通过位移可以给予用户直观的反馈。例如按钮被点击后稍微向上移动一下。动态布局调整:在一些动态布局中,根据用户的操作或者数据的变化,需要对 View 的位置进行调整。比如在一个可折叠的列表中,展开或折叠某一项时,其他项的位置会发生位移。

Android开发领域创作者 828

深度剖析!Android NestedScrollView事件分发原理全揭秘

在Android中,用户与界面交互产生的事件主要分为触摸事件()、按键事件(KeyEvent)和轨迹球事件()等。其中,触摸事件最为常见,涵盖了手指按下()、移动()、抬起(ACTION_UP)以及取消()等操作,是事件分发处理的核心对象。方法是事件分发的起点,它负责接收触摸事件,并决定事件的流向。// NestedScrollView的dispatchTouchEvent方法@Override// 检查是否启用了嵌套滚动功能// 处理嵌套滚动相关的触摸事件。

Android开发领域创作者 730

揭秘 Android View 事件分发机制:源码深度剖析

Android View 的事件分发机制是指当用户触摸屏幕时,系统会将触摸事件(如按下、移动、抬起等)从最顶层的 View 开始,依次向下传递,直到找到合适的 View 来处理该事件的过程。这一机制的主要作用是确保用户的触摸事件能够被正确地处理,同时避免事件的混乱和冲突。通过合理地处理事件分发,开发者可以实现各种复杂的交互效果,如滑动菜单、多点触摸等。方法是事件分发的起点,它负责将触摸事件分发给子 View 或自己处理。// 分发触摸事件的方法// 检查事件是否为按下事件。

Android开发领域创作者 1143

Android触摸事件MOVE状态异常解析与优化方案

Android触摸事件机制是移动开发的核心基础,其事件分发流程从硬件驱动层贯穿至应用层。当触摸屏采样率过高或厂商ROM定制导致InputDispatcher过滤策略差异时,会出现零位移MOVE事件的异常触发。这种现象在华为EMUI等定制系统上尤为明显,涉及触摸灵敏度与事件过滤阈值的底层调控。通过分析MotionEvent的ACTION_MOVE触发原理和getHistoricalX/Y采样数据,开发者需要实现位移判断和时间窗口等优化方案,同时注意ViewConfiguration.getTouchSlop(

weixin_28285943的博客 242

Fab库源码深度剖析:从设计模式到实现原理

Fab库是一个专为Android平台设计的Floating Action Button(悬浮操作按钮)库,它提供了丰富的动画效果、自定义样式和交互功能,帮助开发者快速实现符合Material Design规范的悬浮按钮。本文将从设计模式、核心类结构和实现原理三个维度,深入解析Fab库的源码架构,为开发者提供全面的技术参考。 ## 一、核心类结构:面向对象设计的典范 Fab库采用了清晰的类层次结

gitblog_00885的博客 981
上一篇: Handler的深度剖析
下一篇: [协程]-简单入门
PokeMa
博客等级 码龄10年 101粉丝 28原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值