在自定义VIew过程中,我们必须要对view进行测量,告诉系统改画一个多大的view。
view的测量在onMeasure()方法中进行。
Android系统提供给我们一个类--MeasureSpec类。
测量模式有三种:
- EXACTLY:精确值模式,将控件的layout_width或layout_heigh属性指定为具体数值时,android:layout_with="100dp"。或者指定为match_parent属性时。
- AT_MOST:最大值模式,layout_width或layout_heigh属性设为wrap_content时。控件大小随控件的子空间或内容的变化而变化,不要超过父控件允许的最大尺寸即可。
- UNSPECFIED:不指定其大小的测量模式,View像多大就多大,通常在绘制自定义view时才会使用。
View默认的onMeasure()方法只支持EXACTLY模式,所以可以指定控件的具体宽高值或者match_parent属性,如果要自定义的view支持wrap_content属性,就必须重写onMeasure()方法。
在源码中找到onMeasure()方法
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}```
可以看到,onMeasure()方法最终调用的是
```setMeasuredDimension(getDefaultSize(getSuggestedMinimumWidth(), widthMeasureSpec),
getDefaultSize(getSuggestedMinimumHeight(), heightMeasureSpec));```
onMeasure默认的实现仅仅调用了setMeasuredDimension,setMeasuredDimension函数是一个很关键的函数,它对View的成员变量mMeasuredWidth和mMeasuredHeight变量赋值,而measure的主要目的就是对View树中的每个View的mMeasuredWidth和mMeasuredHeight进行赋值,一旦这两个变量被赋值,则意味着该View的测量工作结束。
所以,view的测量主要分为以下步骤:
- 从MeasureSpec中提取测量模式和大小。
int specMode=MeasureSpec.getMode(measureSpec);//宽度的测量模式
int specSize=MeasureSpec.getSize(measureSpec);//宽度的测量值的大小```
- 通过判断测量值的模式,给出不同的测量值。
1.当specMode为EXACTLY模式时,直接使用specSize即可。
2.当specMode是其他两种模式时,需要给它一个默认的大小。
3.如果想使用wrap_content属性,即specMode为AT_MOST模式时,需要取一个指定的大小和specSize的最小值作为自后的测量值。
private int measureWidth(int measureSpec){
int result=0;
int specMode=MeasureSpec.getMode(measureSpec);//宽度的测量模式
int specSize=MeasureSpec.getSize(measureSpec);//宽度的测量值的大小
if (specMode==MeasureSpec.EXACTLY){//EXACTLY模式
result=specSize;
}else {
result=400;
if (specMode==MeasureSpec.AT_MOST){
result=Math.min(result,specSize);
}
}
return result;
}
- 通过在xml布局文件中更改view的布局查看效果。
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.hybunion.customview.activity.MyMeasureActivity">
<com.hybunion.customview.view.MyMeasure
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#567890"
/>
</RelativeLayout>```
![20160819115233536 (1).jpg](https://img.haomeiwen.com/i3897939/f5da570b953642d9.jpg?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
代码下载 https://github.com/baojie0327/ViewAndGroup
网友评论