十三、View测量、布局、绘制原理

1.View绘制的流程框架

绘制流程图

view的绘制是从上往下一层层迭代下来。DecorView --> ViewGroup( --> ViewGroup) --> View,按照这个流程往下,依次measure(测量),layout(布局),draw(绘制)。


image.png

二、Measure流程

调用measure()方法,进行一些逻辑处理,然后调用onMeasure()方法,在其中调用setMeasuredDimension()设置View的宽高信息,完成View的测量操作。

    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        setMeasuredDimension(getDefaultSize(getSuggestedMinimumWidth(), widthMeasureSpec),
                getDefaultSize(getSuggestedMinimumHeight(), heightMeasureSpec));
    }

如果有widthMeasureSpec,heightMeasureSpec,通过一定的处理(可以重写,自定义处理步骤),从中获取View的宽/高,调用setMeasuredDimension(),指定View的宽高,完成测量的工作。

MeasureSpec的确定

MeasureSpec释义:

image.png

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的测量流程:
View的测量流程

三、Layout流程

测量完View大小后,就需要将View布局在Window中,View的布局主要通过上下左右四个点来确定的。
其中布局也是自上而下,不同的是ViewGroup先在layout()中确定自己的布局,然后在onLayout()方法中再调用子View的layout()方法,让子View布局。在Measure过程中,ViewGroup一般是先测量子View的大小,然后再确定自身的大小。
如果当前View就是一个单一的View,那么没有子View,就不需要实现onLayout方法。如果当前View是一个ViewGroup,就需要实现onLayout方法,该方法的实现与自定义ViewGroup时其特性相关,必须自己实现。由此便完成了一层层的布局工作。
View的布局流程:


View的布局流程

四、Draw过程

View的绘制过程遵循如以下几步。

  • a.绘制背景 background.draw(canvas);
  • b.绘制自己(onDraw)
  • c.绘制Children(dispatchDraw)
  • d.绘制装饰 (onDrawScrollBar)
    从源码中可以清楚地看出绘制的顺序。

无论是ViewGroup还是单一的View,都需要实现整套流程,不同的是,在ViewGroup中,实现了disPatchDraw(),而在单一子View中不需要实现该方法。自定义View一般要重写onDraw()方法,在其中绘制不同的样式。
view绘制流程:


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都需要实现该方法,因其是个空方法。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,732评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,496评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,264评论 0 338
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,807评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,806评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,675评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,029评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,683评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 41,704评论 1 299
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,666评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,773评论 1 332
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,413评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,016评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,978评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,204评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,083评论 2 350
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,503评论 2 343

推荐阅读更多精彩内容