View绘制之---onMeasure()

本篇承接上一篇onMeasure(0,0)究竟发生了什么
整篇文章基于该图
这里写图片描述
对于最上面的原生View,我们没有给定任何参数,只是将他的颜色设置为Red,外层布局都是-1,那么显示出来的结果是,全屏的红色,即这个View占满了全屏,so,why?
所以,我们来看一看父亲是怎么测量这个儿子的。
addView()往里面走有这么段代码

params = generateDefaultLayoutParams();

即给没有param孩子生成一个默认的参数

 protected LayoutParams generateDefaultLayoutParams() {
        return new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
    }

两个都是-2.
父亲测量孩子都会调用下面的方法getChildMeasureSpec,他的作用就是父亲给出MeasureSpec,子类给出LayoutParams,经过一系列计算得出子类的MeasureSpec。
那么,关键点在我们需要真真切切的知道父亲的两个MeasureSpec究竟是什么,那么我就
通过打断点的方式来看,而不是随口说哦。
这里写图片描述
我用的是320x480分辨率的
后面16进制的140换算成10进制就是320
197就是407
我们知道32位的MeasureSpec,前两位表示模式
8=1000,前两位就是10,即2,表示的是AT_MOST(public static final int AT_MOST = 2)
在这里多说几句啊 ,为什么MyLinearLayout的两个参数的模式是2呢?
我的根布局是MyRelativeLayout,两个参数是-1,-1 ,先看看他是怎么测孩子的
还是这个方法getChildMeasureSpec,父亲传给他的模式是。。。问题又来了,这么下来还得了,好吧,我们直接看DecroView的参数吧。
这里写图片描述
如你所想,1e0的10进制就是480。
也许我们大家都还记得一个id为content的FrameLayout吧,也就是我们的内容父类。
这里写图片描述
他的两个参数是4=0100,即1,也就是EXACTLT,后面宽高的分别是320,407.
这里写图片描述
所以,我们现在来关注一下那个FrameLayout是怎么测量我的MyRelativeLayout。好了,终于可以安静的分析一下ViewGroup中的getChildMeasureSpec方法了,此时父类的模式是1,子类的param都是-1,那么

case MeasureSpec.EXACTLY:
            if (childDimension >= 0) {
                resultSize = childDimension;
                resultMode = MeasureSpec.EXACTLY;
            } else if (childDimension == LayoutParams.MATCH_PARENT) {
                // Child wants to be our size. So be it.
                resultSize = size;
                resultMode = MeasureSpec.EXACTLY;

子类的大小就是父类的大小,模式为1(EXACTLY)
ok,再看我的MyLinearLayout ,依然断点走起来 。
其param是两个-2.
结果可以从上图看见了,但还是分析一下吧

else if (childDimension == LayoutParams.WRAP_CONTENT) {
                // Child wants to determine its own size. It can't be
                // bigger than us.
                resultSize = size;
                resultMode = MeasureSpec.AT_MOST;

哦,终于明朗了。
这样一层层走下来,整个体系就很明显了,当我们进行自定义View的时候,可以很容易的根据实际的需求来重写不同的方法。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值