Android View 的绘制流程

整体流程

View 绘制中主要流程分为measure,layout, draw 三个阶段。

  • measure :根据父 view 传递的 MeasureSpec 进行计算大小。(测量)

  • layout :根据 measure 子 View 所得到的布局大小和布局参数,将子View放在合适的位置上。(摆放)

  • draw :把 View 对象绘制到屏幕上。(绘制)
    那么发起绘制的入口在哪里呢?
    首先看一下图解:
    在这里插入图片描述我们需要先了解Window,ViewRootImpl,DecorView之间的联系。
    一个 Activity 包含一个Window,Window是一个抽象基类,是 Activity 和整个 View 系统交互的接口,只有一个子类实现类PhoneWindow,提供了一系列窗口的方法,比如设置背景,标题等。一个PhoneWindow 对应一个 DecorView 跟 一个 ViewRootImpl,DecorView 是ViewTree 里面的顶层布局,是继承于FrameLayout,包含两个子View,一个id=statusBarBackground 的 View 和 LineaLayout,LineaLayout 里面包含 title 跟 content,title就是平时用的TitleBar或者ActionBar,contenty也是 FrameLayout,activity通过setContent()加载布局的时候加载到这个View上。ViewRootImpl 就是建立 DecorView 和 Window 之间的联系。

    这三个阶段的核心入口是在 ViewRootImpl 类的 performTraversals() 方法中。
    就是判断根据之前的状态判断是否需要重新 measure,是否需要重新 layout ,是否需要重新 draw。

    measurespeac

    MeasureSpec 封装了从父View 传递给到子View的布局需求。每个MeasureSpec代表宽度或高度的要求。每个MeasureSpec都包含了size(大小)和mode(模式)。
    MeasureSpec 一个32位二进制的整数型,前面2位代表的是mode,后面30位代表的是size。mode 主要分为3类,分别是

  • EXACTLY:父容器已经测量出子View的大小。对应是 View 的LayoutParams的match_parent 或者精确数值。

  • AT_MOST:父容器已经限制子view的大小,View 最终大小不可超过这个值。对应是 View 的LayoutParams的wrap_content

  • UNSPECIFIED:父容器不对View有任何限制,要多大给多大,这种情况一般用于系统内部,表示一种测量的状态。(这种不怎么常用,下面分析也会直接忽略这种情况)

    View 的 MeasureSpec 并不是父 View 独自决定,它是根据父 view 的MeasureSpec加上子 View 的自己的 LayoutParams,通过相应的规则转化

    measure

    measure 主要功能就是测量设置 View 的大小。该方法是 final 类型,子类不能覆盖,在方法里面会 调用 onMeasure(),我们可以复写 onMeasure() 方法去测量设置 View 的大小。

    layout

    measure() 方法中我们已经测量出View的大小,根据这些大小,我们接下来就需要确定 View 在父 View 的位置进行排版布局,这就是layout 作用。
    对 View 进行排版布局,还是要看父 View,也就是 ViewGroup。

    draw

    经过前面两部的测量跟布局之后,接下来就是绘制了,也就是真正把 View 绘制在屏幕可见视图上。draw()作用就是绘制View 的背景,内容,绘制子View,还有前景跟滚动条。

    详细可参考View 绘制的整体流程
    代码简单讲解

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值