view的绘制流程

view的绘制是从viewRoot的performTraversals开始的。然后依次调用performMeasure,performLayout,performDraw,来完成顶级view的measure,layout,draw。measure会测量view的宽和高,measure完可以通过getMeasureWidth和getMeasureHeight获取view的测量后的宽和高。layout过程则是决定view的四个顶点和最后的view的宽和高。draw则是进行具体的绘制流程。
先来分析measure过程。measure过程中最重要的一个是MeasureSpec,根据英文名可知这是一个测量规格,它是一个32位的int值,高两位为specMode,后30位为specSize.我们可以通过makeMeasureSpec来将specMode和specSize进行打包成MeasureSpec,同样也可以通过getMode和getSize来将measureSpec解包成specMode和specSize.
specMode有三种模式:unspecified,exactly,AT_MOST。
unspecified:父容器不对view有任何限制。
exactly:父容器已经检测出view所需的精确大小,此时view的大小就是specSize.
AT_MOST:父容器指定一个值,view的大小不能大于这个值。
view的measure方法是一个final方法,所以它的子类不能重写该方法,但是measure方法里最终是调用onMeasure方法来测量具体的view的,所以只需要重写onMeasure方法即可。我们来看view的onMeasure方法
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
setMeasuredDimension(getDefaultSize(getSuggestedMinimumWidth(), widthMeasureSpec),
getDefaultSize(getSuggestedMinimumHeight(), heightMeasureSpec));
}
其中getDefaultSize就是在specMode为unspecified时返回传进来的size作为测量大小,在specMode为AT_MOST和exactly时返回specSize作为测量大小。
再看传进来的size为getSuggestdMinimumWidth和getSuggestMinimumHeight的返回值。在看过getSuggestdMinimumWidth源码后就可以知道返回的是minWidth和背景中大的值(背景和minWidth没有则为0).(getSuggestdMinimumHeight同理).
在这里面有一个问题就是当继承view的自定义控件的layoutparams为wrap_content时它的specMode为AT_MOST,此时测量大小就是specSize,而此时specSize就是parentSize,这样就跟match_parent效果是一样的。所以我们需要重写OnMeasure中来处理。
ViewGroup的measure流程。viewGroup不仅要测量自己的大小还要测量它的子元素的大小。所以viewGroup里面有一个measureChildren方法去遍历子元素,调用子元素的measure方法测量子元素。它的onMeasure则需要根据不同布局进行测量。如linearlayout的onMeasure中就根据是Vertical还是horizontal分别调用不同的方法测量自身。
至此view和viewGroup的measure过程就分析完了。layout就是viewGroup用来确定子元素位置的方法。总的来说layout先确认view自身的位置,里面又调用onLayout来调用子元素的layout方法从而将layout过程传递到子元素。view和viewGroup都没有具体的实现onLayout方法,都需要继承他们的控件自己去具体的实现。layout通过setFrame来确定view的四个顶点,此时view的位置就确定了。
draw过程就是具体的绘制过程。首先绘制背景(无则跳过),然后绘制view内容,再遍历子元素进行绘制(通过dispatchDraw来进行传递),最后绘制滑动轴等装饰。
以上就是view的绘制流程,理解绘制流程可以更好的完成需要的自定义view。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值