Android View 的绘制流程(二)

2020-03-22  本文已影响0人  刘小厨

承接上篇文章Android View的绘制流程(一)

这篇承接上篇,主要说下View绘制流程的具体细节核心方法

下面依次分析

\color{blue}{measure() }

其实\color{blue}{measure() }的一系列操作,只做了一件事,就是赋值\color{blue}{measureWidth }\color{blue}{measureHeight},就是确定控件的测量宽高,在测量确定宽高的时候,我们要理解一个很重要的概念:\color{red}{MeasureSpec }

\color{blue}{MeasureSpec } = 模式 + 尺寸

MeasureSpec 是对View宽高属性的封装,是一个32位的int值,前两位表示模式,后30位表示尺寸 及SpecModel+SpecSize
View中定义了三个SpecModel常量,名字和含义分别为:

public static final int UNSPECIFIED = 0 << MODE_SHIFT; 00000000000000000000000000000000

父容器不对View做任何限制,一般是系统内部使用

public static final int EXACTLY     = 1 << MODE_SHIFT; 01000000000000000000000000000000

父容器检测出View的大小,View的大小就是SpecSize 对应布局属性LayoutPamras match_parent以及固定大小

public static final int AT_MOST     = 2 << MODE_SHIFT; 10000000000000000000000000000000

父容器指定一个可用大小,View的大小不能超过这个值,LayoutPamras wrap_content

ViewGroup和View测量确定宽高的流程:

ViewGroup measure --> onMeasure(测量子控件的宽高)--> setMeasuredDimension -->setMeasuredDimensionRaw(保存自己的宽高)

View measure --> onMeasure --> setMeasuredDimension -->setMeasuredDimensionRaw(保存自己的宽高)

注: 在自定义View时候,一定要重写onMeasure方法,否则View在布局中设置wrap_contentmatch_parent效果一样,自定义View要重写onMeasure方法重新确定自己的宽高,自定义ViewGroup要重写onMeasure确定子控件宽高,从而确定自身的宽高
详见Android自定义View的wrap_content无效?

\color{blue}{Layout() }

layout方法主要是确定控件的左上右下的值,主要逻辑在View的setFrame()方法中实现
ViewGroup layout(来确定自己的位置,4个点的位置) -->onLayout(进行子View的布局)
View layout(来确定自己的位置,4个点的位置)

layout方法还调用了自身的onLayout()方法,这个方法在View中是一个protected的空方法,供子类实现,

\color{blue}{Draw() }

draw方法主要做了以下事情

     *      1. Draw the background   绘制背景
     *      2. If necessary, save the canvas' layers to prepare for fading 如果需要进行图层的保存
     *      3. Draw view's content 绘制自身的内容
     *      4. Draw children 绘制子控件 dispatchDraw()方法
     *      5. If necessary, draw the fading edges and restore layers 
     *      6. Draw decorations (scrollbars for instance) 绘制装饰

综上: 在自定义View的过程中需要重写以下方法:
onMeasure()-> onLayout()->onDraw()
如果自定义View是个容器,那么 onLayout()重写之后确定子View的布局,如果是个View,可以不重写这个方法,onDraw()是个可选项,比如重写的View中包含的都是系统控件,可以选择不重写这个方法.

上一篇下一篇

猜你喜欢

热点阅读