自己定义控件的onMeasure方法具体解释

在我们自己定义控件的时候可能你会用到onMeasure方法,以下就具体的给大家介绍一下这种方法:

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
         super.onMeasure(widthMeasureSpec, heightMeasureSpec);
    }

我们自己定义一个类继承View或者ViewGroup之后重写onMeasure方法,我们看到这种方法传递进来两个变量,这里做一下解释:
widthMeasureSpec:推荐的宽度和宽度的计算模式
heightMeasureSpec:推荐的高度和高度的计算模式
这里为什么说是推荐的宽和高呢?
由于这种方法是測量的作用,顾名思义就是让你測量一下你自身的宽和高,传递进来的变量仅仅是提供你作为參考,你依据这些參考值来计算你自身的宽和高!


那么有的人又有疑问了,你说的上面两个值的意思是推荐的宽和高以及响应的计算模式,可我怎么就看到两个值啊,你说的明明就是四个嘛?
这是由于一个变量里面包括了两个变量的值,所以我们须要对这两个值进行操作,获取相应的宽和高和相应的计算模式

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        // super.onMeasure(widthMeasureSpec, heightMeasureSpec);

        // 宽和高的计算模式
        int modeWidth = MeasureSpec.getMode(widthMeasureSpec);
        int modeHeight = MeasureSpec.getMode(heightMeasureSpec);

        //真正的宽和高的数值
        int sizeWidth = MeasureSpec.getSize(widthMeasureSpec);
        int sizeHeigth = MeasureSpec.getSize(heightMeasureSpec);

        measureChildren(widthMeasureSpec, heightMeasureSpec);

        setMeasuredDimension(sizeWidth, sizeHeigth);

    }

能够看到我们通过类MeasureSpec的静态方法能够获取到对应的计算模式和宽和高
事实上计算模式就是你在布局文件里写的match_parent、wrap_content
而获取出来的宽和高是当前的计算模式下父容器所能给你的最大宽和高
比方:
父容器320*480
你这个控件的宽和高用了match_parent
那么这里推荐你的宽和高就是320*480
计算模式就是一个match_parent常量:
ViewGroup.LayoutParams.MATCH_PARENT

假如你用了wrap_content,那么这里推荐你的宽和高还是320*480
计算模式就是一个wrap_content常量:
ViewGroup.LayoutParams.WRAP_CONTENT

为什么推荐的宽和高和match_parent的时候一样,由于父容器无法确定你的包裹内容的须要的宽和高详细是多少,所以它仅仅能给你它最大的.所以这种方法计算的时候事实上说白了就是计算包裹内容的时候自身的大小,由于不管是match_parent还是写死的大小父容器都能非常轻松的算出来你须要的大小,仅仅有在包裹的时候是不知道的,须要你自己计算,然后通知我,怎样通知呢?


通过方法:setMeasureDimension(int,int)来告知,这里面就是传入你计算好的真正的宽和高.所以在不是包裹内容的时候父容器推荐你的宽和高是正确的,你无须计算,直接走父类的方法就可以,所以一般的解决方法就是以下这样:
    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        // 宽和高的计算模式
        int modeWidth = MeasureSpec.getMode(widthMeasureSpec);
        int modeHeight = MeasureSpec.getMode(heightMeasureSpec);
        //拿到父容器推荐的宽和高
        int sizeWidth = MeasureSpec.getSize(widthMeasureSpec);
        int sizeHeigth = MeasureSpec.getSize(heightMeasureSpec);
<span style="white-space:pre">	</span>//这里測量每个孩子的宽和高
        if (modeWidth == MeasureSpec.ATMOST)
            //sizeWidth = 计算的值
        }
        if (modeHeight == MeasureSpec.ATMOST<span style="font-family: Arial, Helvetica, sans-serif;">)</span>
            //sizeHeigth = 计算的值
        }
        setMeasuredDimension(sizeWidth, sizeHeigth);
    }

好了今天如此具体的解说了这种方法的作用及其參数的作用,大家自己也去试试吧
原文地址:https://www.cnblogs.com/yutingliuyl/p/7002972.html