Android视图绘制和事件分发相关

本文详细探讨了Android视图的绘制原理,包括Activity如何设置View到PhoneWindow,以及绘制流程中的measure、layout和draw阶段。此外,还讨论了双缓冲技术在Android屏幕绘制中的应用。在事件分发部分,介绍了View事件分发的递归过程,包括如何在ViewGroup中拦截和传递事件,以及如何阻止事件的上一级拦截。
摘要由CSDN通过智能技术生成

绘制原理

Activity -包含-> PhoneWindow -继承于-> Window
Activity -setContentView()-> 将View设置到PhoneWindow上
PhoneWindow -包含-> DecorView(布局容器)

View -持有-> mAttachInfo(与WindowManagerService(WMS)链接) -持有-> ViewRootImpl
ViewRootImpl -有内部类-> W -继承于-> IWindow.Stub(实则是一个Binder,用于接收WMS传递的消息)
ViewRootImpl -有内部类-> ViewRootHandler -继承于-> Handler(用于接收W类的异步消息)
WindowManagerService(负责窗口的创建、显示) <-直接交互-> WindowManger <-直接交互-> ViewRootImpl

View重绘

ViewRootHandler -handleMessage(Message)-> 接收消息 -scheduleTraversals()-> 调用mTraversalRunnable刷新遍历View树

mTraversalRunnable -执行-> performTraversals():

  • 判断需要重新计算试图大小 -执行-> performMeasure()
  • 判断需要重新计算视图位置 -执行-> performLayout()
  • 判断需要重新绘制 -执行-> performDraw()}

View重绘原因:视图本身内部状态(enable,pressed等)变化;View内部添加或者删除了View;View本身的大小和可见性发生了变化

View绘制流程

performTraversals() -> performMeasure() -> performLayout() -> performDraw()

Android屏幕绘制

performDraw() -> draw() -> drawSoftware() -> 通过Suface.lockCanvas()拿到Canvas绘图

双缓冲技术

显示器刷新时,视频控制器按照垂直同步信号从帧缓冲区取帧数据传递给显示器显示,双缓冲区则在数据刷新时将一个缓冲区中的数据直接替换另一个缓冲区

View事件分发——递归

传递过程中,当前层级执行child.dispatchTouchEvent:

  • 如果child是ViewGroup,执行ViewGroup重写的dispatchTouchEvent方法,判断是否在当前层级拦截当前事件或传递给下一级

  • 如果child是没有child的View或ViewGroup,执行View实现的super.dispatchTouchEvent方法,判断:

    • 如果enabled并实现了onTouchListener,且onTouch()返回true,那么直接返回结果
    • 否则执行onTouchEvent(),如果clickable并且实现了onClickListener或onLongClickListener,那么执行 onClick()或onLongClick()
  1. ViewGroup可以在当前层级设置onInterceptTouchEvent()方法返回true来拦截事件的下发
  2. child也可以通过getParent.requestDisallowInterceptTouchEvent()方法来阻止上一级的下发拦截(差异化地配置阈值来确保 child 执行该方法优先于父容器onInterceptTouchEvent()返回true)
  3. 拦截 != 消费,唯有当前层级的super.dispatchTouchEvent()返回了true,才被认定为消费
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值