View的三大流程

首先一个view的绘制是由viewrootimpl中的performTraversals的方法开始执行measure,layout,draw三个方法。

具体的viewrootimpl是什么。看一段源码的注释,了解一下。


二个关键词:最高层级的view,view与windowmanager的纽带。

具体的方法调用流程如图所示:



1.onMeasure

1.1measurespec

在我们覆写了onMeasure方法后,我们会发现方法里有两个参数int widthMeasureSpec, int heightMeasureSpec

我们可以把它理解为规格,测量的规格。

MeasureSpec是代表一个32位的int值,高2位代表spec的mode,低30位代表size。

因此我们可以提前得知,MeasureSpec的mode最多有4种,那到底有几种呢?


1.2specmode 的三种模式

SpecMode一共有三种

1.Unspecified

表示父容器不对view有任何限制,要多大就多大,为所欲为

2.Exactly

顾名思义,父容器已经知道你的大小了,例如match parent,或者具体layoutparams中的数值。

3.atmost

父容器制定了一个specsize,view的大小不能超过这个值。例如,wrap-content。


1.3measurespec 与layoutparam的对应关系

可以这样理解,view的measurespec由父容器的measurespec和自身的layoutparam决定。有人会问,那decorview又没有父容器?decorview的父容器,可以理解成window,decorview的measurespec是由windowsize和自身layoutparam决定。

1.4 onMeasure

onMeasure源码很简单,就是调用了一下setMeasuredDimension(getDefaultSize(getSuggestedMinimumWidth(), widthMeasureSpec),

        getDefaultSize(getSuggestedMinimumHeight(), heightMeasureSpec));复制代码

getSuggestedMinimumWidth的逻辑是,如果view没有设置背景,那么返回android:minWidth这个属性所指定的值,如果view设置了背景,那么返回android:minWidth和背景两者之间最大的。

public static int getDefaultSize(int size, int measureSpec) {
    int result = size;
    int specMode = MeasureSpec.getMode(measureSpec);
    int specSize = MeasureSpec.getSize(measureSpec);

    switch (specMode) {
    case MeasureSpec.UNSPECIFIED:
        result = size;
        break;
    case MeasureSpec.AT_MOST:
    case MeasureSpec.EXACTLY:
        result = specSize;
        break;
    }
    return result;
}复制代码

再来看下此方法,ATMOST 和EXACTLY,的size就直接等于父容器的measuresize。

因此如果直接继承view的自定义控件,不处理wrapcontent,那么效果和matchparent是一样的,都直接等于父容器的剩余大小。像Textview,imageview都特殊处理的wrapcontent。

1.5如何在activity中得到view的测量宽高

1.onWindowFocusChanged

2.view.post

3.ViewTreeObserver

4.view.measure()

这里要根据具体情况来判断。
1.如果view的layoutparam是matchparent,那么直接放弃,此时还不知道父容器的大小。

2.如果是具体数值,那么就easy多了,measure(数字,就是写在xml里的具体数值,MeasureSpec.Exactly)

3.如果是wrap-content ,可以view.measure(1<<30 - 1, MeasureSpec.ATMOST);


2.onLayout

onlayout方法的用途是viewgroup来设置子view的位置。view的onlayout方法会调用setframe来设置4个顶点的位置,这4个顶点的位置来自于viewgroup对子view的测量。


3.onDraw


ondraw其实没什么特别的内容,只要按照对应的顺序进行绘制。



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值