图解View测量、布局及绘制原理
来源:互联网 发布:淘宝bose官方旗舰店 编辑:程序博客网 时间:2024/04/30 01:29
一、View绘制的流程框架
View的绘制是从上往下一层层迭代下来的。DecorView-->ViewGroup(--->ViewGroup)-->View ,按照这个流程从上往下,依次measure(测量),layout(布局),draw(绘制)。关于DecorView,可以看这篇文章。
二、Measure流程
顾名思义,就是测量每个控件的大小。
调用measure()方法,进行一些逻辑处理,然后调用onMeasure()方法,在其中调用setMeasuredDimension()设定View的宽高信息,完成View的测量操作。
measure()方法中,传入了两个参数 widthMeasureSpec, heightMeasureSpec 表示View的宽高的一些信息。
由上述流程来看Measure流程很简单,关键点是在于widthMeasureSpec, heightMeasureSpec这两个参数信息怎么获得?
如果有了widthMeasureSpec, heightMeasureSpec,通过一定的处理(可以重写,自定义处理步骤),从中获取View的宽/高,调用setMeasuredDimension()方法,指定View的宽高,完成测量工作。
MeasureSpec的确定
先介绍下什么是MeasureSpec?
MeasureSpec由两部分组成,一部分是测量模式,另一部分是测量的尺寸大小。
其中,Mode模式共分为三类
UNSPECIFIED :不对View进行任何限制,要多大给多大,一般用于系统内部
EXACTLY:对应LayoutParams中的match_parent和具体数值这两种模式。检测到View所需要的精确大小,这时候View的最终大小就是SpecSize所指定的值,
AT_MOST :对应LayoutParams中的wrap_content。View的大小不能大于父容器的大小。
那么MeasureSpec又是如何确定的?
对于DecorView,其确定是通过屏幕的大小,和自身的布局参数LayoutParams。
这部分很简单,根据LayoutParams的布局格式(match_parent,wrap_content或指定大小),将自身大小,和屏幕大小相比,设置一个不超过屏幕大小的宽高,以及对应模式。
对于其他View(包括ViewGroup),其确定是通过父布局的MeasureSpec和自身的布局参数LayoutParams。
这部分比较复杂。以下列图表表示不同的情况:
当子View的LayoutParams的布局格式是wrap_content,可以看到子View的大小是父View的剩余尺寸,和设置成match_parent时,子View的大小没有区别。为了显示区别,一般在自定义View时,需要重写onMeasure方法,处理wrap_content时的情况,进行特别指定。
从这里看出MeasureSpec的指定也是从顶层布局开始一层层往下去,父布局影响子布局。
可能关于MeasureSpec如何确定View大小还有些模糊,篇幅有限,没详细具体展开介绍,可以看这篇文章
View的测量流程:
三、Layout流程
测量完View大小后,就需要将View布局在Window中,View的布局主要通过确定上下左右四个点来确定的。
其中布局也是自上而下,不同的是ViewGroup先在layout()中确定自己的布局,然后在onLayout()方法中再调用子View的layout()方法,让子View布局。在Measure过程中,ViewGroup一般是先测量子View的大小,然后再确定自身的大小。
上面看出通过 setFrame() / setOpticalFrame():确定View自身的位置,通过onLayout()确定子View的布局。
setOpticalFrame()内部也是调用了setFrame(),所以具体看setFrame()怎么确定自身的位置布局。
确定了自身的位置后,就要通过onLayout()确定子View的布局。onLayout()是一个可继承的空方法。
如果当前View就是一个单一的View,那么没有子View,就不需要实现该方法。
如果当前View是一个ViewGroup,就需要实现onLayout方法,该方法的实现个自定义ViewGroup时其特性有关,必须自己实现。
由此便完成了一层层的的布局工作。
View的布局流程:
四、Draw过程
View的绘制过程遵循如下几步:
①绘制背景 background.draw(canvas)
②绘制自己(onDraw)
③绘制Children(dispatchDraw)
④绘制装饰(onDrawScrollBars)
从源码中可以清楚地看出绘制的顺序。
无论是ViewGroup还是单一的View,都需要实现这套流程,不同的是,在ViewGroup中,实现了 dispatchDraw()方法,而在单一子View中不需要实现该方法。自定义View一般要重写onDraw()方法,在其中绘制不同的样式。
View绘制流程:
五、总结
从View的测量、布局和绘制原理来看,要实现自定义View,根据自定义View的种类不同,可能分别要自定义实现不同的方法。但是这些方法不外乎:onMeasure()方法,onLayout()方法,onDraw()方法。
onMeasure()方法:单一View,一般重写此方法,针对wrap_content情况,规定View默认的大小值,避免于match_parent情况一致。ViewGroup,若不重写,就会执行和单子View中相同逻辑,不会测量子View。一般会重写onMeasure()方法,循环测量子View。
onLayout()方法:单一View,不需要实现该方法。ViewGroup必须实现,该方法是个抽象方法,实现该方法,来对子View进行布局。
onDraw()方法:无论单一View,或者ViewGroup都需要实现该方法,因其是个空方法
- 图解View测量、布局及绘制原理
- Android中View测量、布局及绘制原理
- Android中View测量、布局及绘制原理
- 深入了解View(四)—— LayoutInflater原理及View测量/布局/绘制总结
- view的测量,布局,绘制
- view的流程(测量,布局,绘制)
- View、ViewGroup的测量、布局、绘制流程
- 自定义控件(一):View的测量及绘制流程、原理简介
- 自定义View:测量measure,布局layout,绘制draw
- 自定义View的绘制原理图解
- View的测量 绘制
- Android控件架构及View、ViewGroup的测量和绘制
- 【安卓开发艺术探索】第4章 View的测量、布局、绘制 笔记
- ViewGroup的测量及绘制
- Android群英传读书笔记---View测量和绘制
- View和ViewGroup的测量与绘制
- 【Android自定义View】测量和绘制浅析
- Android View 绘制流程之测量(一)
- 如何在ubuntu上使用校园网上网
- 文件IO流(二)
- JSP_11th_内置对象
- NumPy学习笔记(4)--数据归一化
- Flink运行时之客户端提交作业图-下
- 图解View测量、布局及绘制原理
- 蓝桥杯-表达式计算-栈的应用
- 匀速动画封装
- 【BZOJ 3295】[Cqoi2011]动态逆序对
- Unity3D优化技巧系列六
- Android自定义View资料
- python-recsys 3 Data model 3 数据模型
- 1983 等式问题
- 算典05_例题_07_UVA-136