Android中View框架的办事体制中,主要有三单经过:

     1、View树的测量(measure)Android View框架的measure机制
     2、View树的布局(layout) Android View框架的layout机制
     3、View树的绘图(draw)Android View框架的draw机制

     View框架的工作流程也:测量每个View大小(measure)–>把每个View放置到相应的职(layout)–>绘制每个View(draw)。

1、系统为什么而发measure过程?

       
开发人员在绘制UI的上,基本还是透过XML布局文件之道来配置UI,而每个View必须要设置的少独群属性就是layout_width和layout_height,这有限单特性代表正在脚下View的尺寸。

法定文档截图:

XML 1

       
所以这半单特性的价是要使指定的,这简单独特性的取值只能为老三种档次:

                 1、固定的分寸,比如100dp。

                 2、刚好包裹中的始末,wrap_content。

                 3、想要同父布局一样很,match_parent / fill_parent。

       
由于Android希望提供一个又优雅的GUI框架,所以提供了于适应之尺寸,也即是
wrap_content 和 match_parent 。

       
试想一下,那如果这些性只允许设置固定的轻重缓急,那么每个View的尺寸在绘制的时即便已规定了,所以可能都非需measure过程。但是出于用满足从适应尺寸的机制,所以待一个measure过程。

 2、measure过程都涉嫌了接触啊事?

       
由于地方提到的从适应尺寸的建制,所以于于是自适应尺寸来定义View大小的时节,View的真尺寸还非克确定。但是View尺寸最终要映射到屏幕及之像素大小,所以measure过程即是关系就档子事,把各种尺寸值,经过测算,得到具体的诸如素值。measure过程会遍历整棵View树,然后逐一测量每个View真实的尺码。具体是每个ViewGroup会向它们里面的每个子View发送measure命令,然后由具体子View的onMeasure()来测量自己的尺码。最后测量的结果保存于View的mMeasuredWidth和mMeasuredHeight中,保存的数额单位凡像素。

3、对于自适应的尺寸机制,如何客观之测量一发View树?

       
系统在遍历完布局文件后,针对布局文件,在内存中变化对应的View树结构,这个时,整棵View树种的备View对象,都还并未现实的尺寸,因为measure过程最终是如果规定每个View打的高精度尺寸,也即是规范的诸如素值。但是恰恰开头之时节,View中layout_width和layout_height两个特性的价值,都止是打适应之尺寸,也即是match_parent和wrap_content,这简单单价值在系遭到呢负数,所以系统未见面管其当成具体的尺寸值。所以当一个View需要将它们里面的match_parent或者wrap_content转换成现实的如素值的当儿,他待明白少个信息。

       
1、针对于match_parent,父布局当前实际像素值是微,因为match_parent就是子View想使与父布局一样好。

       
2、针对wrap_content,子View用基于目前祥和内部的content,算有一个成立之克包裹有情节的绝小价。但是要是这极其小值比较当下父布局还颇,那那个,父布局会报您,我只有如此老,你吗不应超过这个尺寸。

       
由于树这种数量结构的特殊性,我们在研measure的经过不时,可以独自研究一个ViewGroup和2独View的简要场景。大概示意图如下:

XML 2

       
也就是说,在measure过程遭到,ViewGroup会根据自己手上的光景,结合子View的尺寸数据,进行一个归结评比,然后拿相关消息报告子View,然后子View在onMeasure自己之早晚,一边用考虑到好的content大小,一边还要考虑的父布局的限量信息,然后综合评判,测量出一个极其出色的结果。

4、那么ViewGroup是哪向子View传递限制信息之?       

 谈到传递限制信息,那就是是MeasureSpec类了,该类贯穿于所有measure过程,用来传递父布局对子View尺寸测量的格信息。简单来说,该类就保存两类数据。
   1、子View时所当父布局的现实性尺寸。
   2、父布局对子View的限量类。
        那么限制类又分为三种植档次:
               
1、UNSPECIFIED,不限量。意思就是是,子View想使多深,我哪怕得让您多大,你放心大胆的measure吧,不用管其他的。也非用无自己传递让你的尺寸值。(其实    Android高版本被推荐,只要是这模式,尺寸设置为0)
                2、EXACTLY,精确的。意思就是是,根据本人时的景象,结合你指定的尺码参数来设想,你就是当是此尺寸,具体尺寸在MeasureSpec的尺寸属性中,自己失去查吧,你呢毫无管你的content有多特别了,就用是尺寸吧。
                3、AT_MOST,最多的。意思就是是,根据我当下底状,结合而指定的尺寸参数来考虑,在匪越自己吃你限定的尺寸的前提下,你测量一个刚能包裹你情之尺寸就可以了。

源代码分析

        在View的源代码中,提取到了底有有关measure过程的音。

       
我们理解,整棵View树的干净节点是DecorView,它是一个FrameLayout,所以它们是一个ViewGroup,所以整棵View树的测量是起一个ViewGroup对象的measure方法开始之。

View: 1、measure

/**
开始测量一个View有差不多死,parent会在参数中提供约信息,实际的测工作是以onMeasure()中进行的,该方法会调用onMeasure()方法,所以只有onMeasure能被也亟须要给override
*/
public final void measure(int widthMeasureSpec, int heightMeasureSpec);

父布局会在投机的onMeasure方法中,调用child.measure
,这虽将measure过程易到了子View中。

2、onMeasure

/**
具体测量过程,测量view和她的情节,来决定测量的方便高(mMeasuredWidth 
mMeasuredHeight )。该方法中必使调用setMeasuredDimension(int,
int)来保存该view测量的财大气粗高。 */

protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec);

子View会在拖欠法吃,根据父布局给有之限制信息,和友爱之content大小,来合理之测量好的尺码。

3、setMeasuredDimension

/** 保存测量结果 */

protected final void setMeasuredDimension(int measuredWidth, int
measuredHeight);

当View测量结束后,把测量结果保存起来,具体保存于mMeasuredWidth和mMeasuredHeight中。

ViewGroup:

1、measureChildren

/**
让抱有子view测量自己的尺码,需要考虑当下ViewGroup的MeasureSpec和Padding。跳了态吧gone的子view
*/
protected void measureChildren(int widthMeasureSpec, int
heightMeasureSpec);–>getChildMeasureSpec()–>child.measure();

测量所有的子View尺寸,把measure过程及至子View内部。

 2、measureChild

/** 测量单个View,需要考虑当下ViewGroup的MeasureSpec和Padding。 */
protected void measureChild(View child, int parentWidthMeasureSpec, int
parentHeightMeasureSpec);–>getChildMeasureSpec()–>child.measure();

针对每一个现实的子View进行测量。

 

3、measureChildWithMargins

/**
测量单个View,需要考虑当下ViewGroup的MeasureSpec和Padding、margins。
*/
protected void measureChildWithMargins(View child, int
parentWidthMeasureSpec, int widthUsed, int parentHeightMeasureSpec, int
heightUsed);–>getChildMeasureSpec()–>child.measure();

对各一个切实可行的子View进行测量。但是用考虑到margin等消息。

 4、getChildMeasureSpec

/**
measureChildren过程被极度艰苦的平局部,为child计算MeasureSpec。该措施为每个child的每个维度(宽、高)计算是的MeasureSpec。目标就是是拿当前viewgroup的MeasureSpec和child的LayoutParams结合起来,生成绝合情合理之结果。
比如,当前ViewGroup知道好的可靠尺寸,因为MeasureSpec的mode为EXACTLY,而child希望会match_parent,这时便会见呢child生成一个mode为EXACTLY,大小也ViewGroupXML大小的MeasureSpec。
 */

public static int getChildMeasureSpec(int spec, int padding, int
childDimension);

据悉当下自家之场景,以及特定子View的尺码参数,为特定子View计算一个客观之限信息。

源代码:

相关文章

网站地图xml地图