View绘制流程

ViewRootImpl.performTraversals流程:

measure、layout、draw流程:

Measure:

①单一View:measure() -> onMeasure() -> getDefaultSize() 计算View的宽/高值 -> setMeasuredDimension存储测量后的View宽/高
②ViewGroup:
-> measure()
-> 需要重写onMeasure,ViewGroup没有定义测量的具体过程,是一个抽象类,其测量过程的onMeasure方法需要各个子类去实现,遍历测量ViewGroup中所有的View。如:LinearLayout、RelativeLayout、FrameLayout等等,这些控件的特性都是不一样的,测量规则自然也都不一样。
-> 根据父容器的MeasureSpec和子View的LayoutParams等信息计算子View的MeasureSpec
-> 合并所有子View计算出ViewGroup的尺寸
-> setMeasuredDimension 存储测量后的宽 / 高。

Layout:

根据上一步measure子View所得到的布局大小和布局参数,从顶层父View向子View递归调用view.layout方法确定各元素的位置,子元素如果是 ViewGroup 的子类,再次执行 onLayout,如此循环往复,直到所有子元素的位置都被确定,整个 View 树的 layout 过程就执行完了。

Draw:

绘制视图。ViewRoot创建一个Canvas对象,然后调用OnDraw()。

六个步骤:

①绘制视图背景;

②保存画布图层(Layer);

③绘制View内容;

④绘制View的子视图,如果没有就不用;

⑤还原图层(Layer);

⑥绘制View装饰(例如滚动条等等)。

MeasureSpec是什么?

MeasureSpec是一个32位的整形值,它的高2位表示测量模式SpecMode,低30位表示规格大小SpecSize。MeasureSpec是View类的一个静态内部类,用来说明应该如何测量这个View。它有三种测量模式:

EXACTLY:精确测量,视图宽高指定为match_parent或具体数值时生效,表示父视图已经决定了子视图的精确大小,这种模式下View的测量值就是SpecSize的值。

AT_MOST:最大值,当视图的宽高指定为wrap_content时生效,此时子视图的尺寸可以是不超过父视图允许的最大尺寸的任何尺寸。

UNSPECIFIED:不指定,父视图没有限制子视图的大小,子视图可以是想要的任何尺寸,通常用于系统内部,应用开发中很少用到。

MeasureSpec通过将SpecMode和SpecSize打包成一个int值来避免过多的对象内存分配,为了方便操作,其提供了打包和解包的方法,打包方法为makeMeasureSpec,解包方法为getMode和getSize。

子View创建MeasureSpec的规则是什么?

根据父容器的MeasureSpec和子View的LayoutParams等信息计算子View的MeasureSpec

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值