Android自定义View之onMeature解析

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

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的宽高为:
.com.mhotfix.MView
        android:id="@+id/mview"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:background="@android:color/holo_green_dark"
        />

Android自定义View之onMeature解析_第1张图片

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

Android自定义View之onMeature解析_第2张图片
这里不太好展示,其实屏幕还没有完全沾满的,长宽分别是500dp

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

Android自定义View之onMeature解析_第3张图片
这里完全占满屏幕。

你可能感兴趣的:(android基础知识)