Android自定义view-onMeasure

Andorid view 的onMeasure():

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

1. 理解MeasureSpec

onMeasure方法参数可以看到两个int值,那么怎么通过他来获取测量信息呢?
其实MeasureSpec是一view的内部类,其封装了view的规格尺寸。他有一个很重要的常量,就是一个32位的int 值,很巧妙,其中高2位代表了SpecMode,低30位代表了SpecSIze,(从其源码可以看出)

  • SpecMode 指测量模式:
    • UNSPECIFIED:未指定模式未指定模式,View想多大就多大,父容器不做限制,一般用于系统内部的测量
    • AT_MOST:最大模式,对应于wrap_comtent属性,子View的最终大小是父View指定的SpecSize值,并且子View的大小不能大于这个值。
    • EXACTLY:精确模式,对应于 match_parent 属性和具体的数值,父容器测量出 View所需要的大小,也就是SpecSize的值

所以一般自定义view需要重写该方法,给出当测量模式为AT_MOST时的默认宽高大小,否则,当设置其宽高为wrap_content时会和match_parent一样

2.view的Measure流程:

measure 用来测量 View 的宽和高,它的流程分为 View 的 measure 流程和 ViewGroup 的measure流程,只不过ViewGroup的measure流程除了要完成自己的测量,还要遍历地调用子元素的measure()方法。
在自定义view的时候,一般需要处理padding和子元素的margin两种情况

3.两种获取view的宽高方法对比:

  • getMeasuredWidth()

    1
    2
    3
    public final int getMeasuredWidth() {
    return mMeasuredWidth & MEASURED_SIZE_MASK;
    }
  • getHeight()

    1
    2
    3
    public final int getHeight() {
    return mBottom - mTop;
    }

    所以从其源码可以看出不同,第一个需要在其onMeasure()方法调用后才能获取到正确的宽高,而第二个需要在onLayout()调用后才能获取到

© 2020 WPY's Android Tour All Rights Reserved. 本站访客数人次 本站总访问量
Theme by hiero