View 的测量
2018-08-22 本文已影响3人
异想天开的骑士
重写 onMeasure 方法
在对 View 进行测量时,要在 onMeasure 方法中使用 setMeasuredDimension 设置测量后的结果。 setMeasuredDimension 方法需要传入两个参数,即测量后的宽和高。下面就来看看如何对宽高进行测量。
onMeasure 方法中有两个参数,分别为父 View 对子 View 宽高的限制。我们在进行测量时需要根据这两个参数取出测量模式和实际大小,我们以宽度为例
int widthMode = MeasureSpec.getMode(widthMeasureSpec);
int widthSize = MeasureSpec.getSize(widthMeasureSpec);
三种测量模式
- EXACTLY:精确值模式。对应布局文件中的 match_parent 或者具体的数值。
- AT_MOST:最大值模式。对应布局文件中的 wrap_content
- UNSPECIFIED:无限制模式。很少用到。
具体测量
假设我们指定 View 的宽高为300px,则可进行如下测量
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
int width = 300;
int height = 300;
setMeasuredDimension(measureWidth(width, widthMeasureSpec),
measureHeight(height, heightMeasureSpec));
}
/**
* 测量宽度
* @param width
* @param widthMeasureSpec
* @return
*/
public int measureWidth(int width, int widthMeasureSpec) {
int widthResult;
int widthMode = MeasureSpec.getMode(widthMeasureSpec);
int widthSize = MeasureSpec.getSize(widthMeasureSpec);
switch (widthMode) {
case MeasureSpec.EXACTLY:
widthResult = widthSize;
break;
case MeasureSpec.AT_MOST:
if (widthSize < width) {
widthResult = widthSize;
} else {
widthResult = width;
}
break;
default:
widthResult = width;
break;
}
return widthResult;
}
当为 EXACTLY 模式时,最终测量结果为父 View 所限制的宽度。
当为 AT_MOST 模式时,最终测量结果为父 View 所限制的宽度与所定义尺寸的最小值。
效果
<com.chrongliu.customviewsample.MeasureView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/colorAccent"/>

<com.chrongliu.customviewsample.MeasureView
android:layout_width="50dp"
android:layout_height="50dp"
android:background="@color/colorAccent"/>

<com.chrongliu.customviewsample.MeasureView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@color/colorAccent"/>
