Android 中View的绘制流程及其自定义


绘制流程

View的绘制是从ViewRoot 的performTraversals方法开始的,流程如下(图片来自《Android开发艺术探索》):
Android 中View的绘制流程

测量

MeasureSpec

概念:MeasureSpec是一个int变量,高两位用来表示SpecMode类型,低30位用来表示SpecSize。MeasureSpec决定了持有该MeasureSpec的View的大小。每个View都持有两个MeasureSpec变量(分别用于决定宽、高)。

由来:一个View的MeasureSpec由自身的LayoutParams(其中的width、height,即xml文件中的layout_width、layout_height)和它的父布局的MeasureSpec 共同决定。创建规则如下图:
MeasureSpec的创建规则
注:顶级View(如DecorView)的MeasureSpec是由窗口尺寸和自身LayoutParams决定。

measure、onMeasure的实现

View的测量包括measure、onMeasure两个步骤。
基类**View中含有:**final measure()、onMeasure()。
基类ViewGroup:并未重写这两个方法。
onMeasure()方法会被View的子类重写(如TextView、LinearLayout。注:ViewGroup并未重写onMeasure())。
若自定义view直接继承View这一基类而不是它的子类如TextView则需要在onMeasure()中处理padding和wrap_content的情况,否则,不需重写onMeasure()。
之所以需要处理wrap_content的情况是因为基类View的onMeasure()方法直接用自身MeasureSpec的specSize决定自身大小,而从上图MeasureSpec的创建规则可知,View自身的specSize在match_parent和wrap_content的情况下都是等于parentSize即它的parentView的specSize。在基类View的onMeasure()方法中也并未对padding做任何处理。

onMeasure需要实现的功能:
1. 遍历子View:调用getChildMeasureSpec()方法(这一方法就是MeasureSpec的创建规则)获得子View的宽和高的MeasureSpec,调用子View的measure()方法。(注意:只有布局才有这一步骤)
2. 据自身的MeasureSpec 设置自身宽高

布局

**基类**View中含有:layout()、abstract onLayout()。
基类**ViewGroup:**final layout()、abstract onLayout()。

layout、onLayout需要实现的功能:
1. layout():确定自身位置。(注:与measure过程不同)
2. onLayout():遍历并调用子View的layout()

绘制

调用canvas的方法并结合Paint来画图。


自定义

自定义View就是重写onMeasure()、onLayout()、onDraw()方法。

具体参考该demo下的Custom View:具有动画效果的饼状图、条形图等

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值