自定义view之onMeasure()的理解

本文主要记录下对于自定义view中方法的理解。
对于自定义view有三大流程:onMeasure(测量)、onLayout(布局)和onDraw(绘制)
接下来我就要说下onMeasure()这个方法:

onMeasure

在布局文件中,对于自定义view的layout_widthlayout_height不设置wrap_content,一般不需要进行处理,但如果要设置wrap_content,就要对宽高进行测量。
onMeasure函数原型
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec)

参数中的widthMeasureSpecheightMeasureSpec里面包含了测量模式和尺寸,在这可以借助Android内置的MeasureSpec类来获取测量模式和尺寸:

int widthMode = MeasureSpec.getMode(widthMeasureSpec);
int widthSize = MeasureSpec.getSize(widthMeasureSpec);

对于测量模式有三种情况:

测量模式 含义
UNSPECIFIED 父容器没有对当前View有任何限制,当前View可以任意取尺寸
EXACTLY 当前尺寸就是当前View应该取的尺寸,对应于match_parent和具体数值情况
AT_MOST 当前View所能取的最大尺寸,一般是给定一个大小,view的尺寸不能超过该大小,一般用于wrap_content

手重写onMeasure函数

@Overrideprotected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
    super.onMeasure(widthMeasureSpec, heightMeasureSpec);

    int width = MeasureSpec.getSize(widthMeasureSpec);
    int widthMode = MeasureSpec.getMode(widthMeasureSpec);
    int height = MeasureSpec.getSize(heightMeasureSpec);
    int heightMode = MeasureSpec.getMode(heightMeasureSpec);

    if (widthMode == MeasureSpec.AT_MOST && heightMode == MeasureSpec.AT_MOST) {
        setMeasuredDimension(WRAP_WIDTH, WRAP_HEIGHT);
    } else if (widthMode == MeasureSpec.AT_MOST) {
        setMeasuredDimension(WRAP_WIDTH, height);
    } else if (heightMode == MeasureSpec.AT_MOST) {
        setMeasuredDimension(width, WRAP_HEIGHT);
    }
}

只处理AT_MOST情况也就是wrap_content,其他情况则沿用系统的测量值即可。setMeasuredDimension会设置View宽高的测量值,只有setMeasuredDimension调用之后,才能使用getMeasuredWidth()getMeasuredHeight()来获取视图测量出的宽高,以此之前调用这两个方法得到的值都会是0。

注意:在覆写onMeasure方法的时候,必须调用 setMeasuredDimension(int,int)来存储这个View经过测量得到的measured width and height。

你可能感兴趣的:(自定义view之onMeasure()的理解)