Android自定义View(一) View的测量

来源:互联网 发布:淘宝卖明星周边违法吗 编辑:程序博客网 时间:2024/05/01 13:47

想要让系统绘制出你所需要的图形,就必须告诉系统View的大小,所以,在绘制View时,先实现View的onMesure()方法。

在测量View之前,要先了解MeasureSpec这个类,MeasureSpec对象中包含了测量的模式和测量的大小;

测量模式

MeasureSpec.EXACTLY 精确模式:当我们将控件的layout_width属性或者layout_height属性指定为具体值的时候,这时候使用的是MeasureSpec.EXACTLY模式
MeasureSpec.AT_MOST 最大值模式,当我们将控件的layout_width属性或者layout_height属性指定为wrap_content时,控件的大小随子控件的大小变化而变化。
MeasureSpec.UNSPECFIED 不指定大小测量模式,View想多大就多大。

重写onMesure()

查看源码可以知道,super.onMeasure()方法最终将测量所得到的值传给了setMeasuredDimension()供系统调用。
   @Override    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {//        super.onMeasure(widthMeasureSpec, heightMeasureSpec);        setMeasuredDimension(mesureWidth(widthMeasureSpec), measureHeight(heightMeasureSpec));    }

测量宽度:
 /**     * 测量宽度     * @param widthMeasureSpec     * @return     */    private int mesureWidth(int widthMeasureSpec) {        int ret = 0;        int specMode = MeasureSpec.getMode(widthMeasureSpec);//1 获取测量模式        int specSize = MeasureSpec.getSize(widthMeasureSpec);//2 获取测量大小        if (specMode == MeasureSpec.EXACTLY) {//3 如果测量模式为MeasureSpec.EXACTLY,直接将测量值返回            ret = specSize;        } else {//4 其他模式需要给一个默认值            ret = 200;            if (specMode == MeasureSpec.AT_MOST) {//如果为 MeasureSpec.AT_MOST,则需要去除specSize与默认值比较,返回最小值                Math.min(ret, specSize);            }        }        return ret;    }

测量高度:(与宽度几乎一样)
 /**     * 测量高度     * @param heightMeasureSpec     * @return     */    private int measureHeight(int heightMeasureSpec) {        int ret = 0;        int specMode = MeasureSpec.getMode(heightMeasureSpec);        int specSize = MeasureSpec.getSize(heightMeasureSpec);        if (specMode == MeasureSpec.EXACTLY) {            ret = specSize;        } else {            ret = 200;            if (specMode == MeasureSpec.AT_MOST) {                Math.min(ret, specSize);            }        }        return ret;    }

注:如果不重写onMeasure()方法,默认情况下,设置wrap_content时,控件会填充父窗体。



0 0