Android自定义View之onMeature解析

来源:互联网 发布:java实现下载断点续传 编辑:程序博客网 时间:2024/05/20 05:55

转载请标明出处:一片枫叶的专栏

android中View在测量的过程中会回调方法:

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

其中widthMeasureSpec和heightMeasureSpec是MeasureSpec类型的数据,我们可以通过它获取绘制模式和数值:

int specMode = MeasureSpec.getMode(measureSpec);int specSize = MeasureSpec.getSize(measureSpec);

android体系的绘制模式有三种(自定义View的绘制模式默认为:EXACTLY):
AT_MOST,specSize 代表的是最大可获得的空间;
EXACTLY,specSize 代表的是精确的尺寸;
UNSPECIFIED,对于控件尺寸来说,没有任何参考意义,可以是任意大小,重要用于自定义。

当我们设置width或height为fill_parent时,容器在布局时调用子view的measure方法传入的模式是EXACTLY,因为子view会占据剩余容器的空间,所以它大小是确定的。
而当设置为 wrap_content时,容器传进去的是AT_MOST, 表示子view的大小最多是多少,这样子view会根据这个上限来设置自己的尺寸。
当子view的大小设置为精确值时,容器传入的是EXACTLY, 而MeasureSpec的UNSPECIFIED模式目前还没有发现在什么情况下使。

自定义View默认的测量模式是:EXACTLY,也就是说,如果自定义View不重写onMeasure方法的话,就只能使用EXACTLY,View只能相应fill_parent或者是具体值,若想view能够识别wrap_content,则需要我们重写onMeasure方法:

@Override    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {        // super.onMeasure(widthMeasureSpec, heightMeasureSpec);        setMeasuredDimension(measureWidth(widthMeasureSpec), measureWidth(heightMeasureSpec));        int specMode = MeasureSpec.getMode(widthMeasureSpec);        int specSize = MeasureSpec.getSize(widthMeasureSpec);        Log.i("tag", "specMode:" + specMode + "  specSize:" + specSize + "  " + MeasureSpec.UNSPECIFIED + "  " + MeasureSpec.AT_MOST + "  " + MeasureSpec.EXACTLY);    }    private int measureWidth(int measureSpec) {        int result = 0;        int specMode = MeasureSpec.getMode(measureSpec);        int specSize = MeasureSpec.getSize(measureSpec);        if (specMode == MeasureSpec.EXACTLY) {            result = specSize;        } else {            result = 200;            if (specMode == MeasureSpec.AT_MOST) {                result = Math.min(result, specSize);            }        }        return result;    }

这样我们再次查看自定义View的显示效果:

  • 当设置自定义View的宽高为:
<uuzuche.com.mhotfix.MView        android:id="@+id/mview"        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:background="@android:color/holo_green_dark"        />

这里写图片描述

  • 当设置自定义View的宽高为:
<uuzuche.com.mhotfix.MView        android:id="@+id/mview"        android:layout_width="500dp"        android:layout_height="500dp"        android:background="@android:color/holo_green_dark"        />

这里写图片描述
这里不太好展示,其实屏幕还没有完全沾满的,长宽分别是500dp

  • 当设置自定义View的宽高为:
<uuzuche.com.mhotfix.MView        android:id="@+id/mview"        android:layout_width="match_parent"        android:layout_height="match_parent"        android:background="@android:color/holo_green_dark"        />

这里写图片描述
这里完全占满屏幕。

3 0
原创粉丝点击