看了不少自定义View的文章,对onMeasure方法中的测量模式一直不理解,今天回顾了以前的知识,做了一个小例子来理解一下
一:自定义一个View
public class CustomView extends TextView {
public CustomView(Context context) {
super(context);
}
public CustomView(Context context, AttributeSet attrs) {
super(context, attrs);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
//宽度
String specMode_width = "";
int specModeWidth = MeasureSpec.getMode(widthMeasureSpec);
switch (specModeWidth) {
case MeasureSpec.EXACTLY:
specMode_width = "EXACTLY";
break;
case MeasureSpec.AT_MOST:
specMode_width = "AT_MOST";
break;
case MeasureSpec.UNSPECIFIED:
specMode_width = "UNSPECIFIED";
break;
}
//高度度
String specMode_height = "";
int specModeHeight = MeasureSpec.getMode(heightMeasureSpec);
switch (specModeHeight) {
case MeasureSpec.UNSPECIFIED:
specMode_height = "UNSPECIFIED";
break;
case MeasureSpec.AT_MOST:
specMode_height = "AT_MOST";
break;
case MeasureSpec.EXACTLY:
specMode_height = "EXACTLY";
break;
}
Log.e("TAG", "specMode_width = " + specMode_width + " , specMode_height = " +
specMode_height);
Log.e("TAG", "specSize_width = " + MeasureSpec.getSize(widthMeasureSpec) + "
, specSize_height = " + MeasureSpec.getSize(heightMeasureSpec));
}
}
二.在布局文件中使用View
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/activity_main"
android:layout_width="match_parent"
android:layout_height="match_parent">
<com.example.customerviewapp.CustomView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@android:color/holo_blue_light"
android:gravity="center"
android:text="hello world"/>
</LinearLayout>
然后运行(屏幕分辨率为:720×1280)
输出结果如下:
1.此时layout_width和layout_height都设置成wrap_content
TAG: specMode_width = AT_MOST , specMode_height = AT_MOST
TAG: specSize_width = 720 , specSize_height = 1280
2.当将layout_width和layout_height都设置成match_parent
TAG: specMode_width = EXACTLY , specMode_height = EXACTLY
TAG: specSize_width = 720 , specSize_height = 1280
3.当将layout_width和layout_height都设置成100px
TAG: specMode_width = EXACTLY , specMode_height = EXACTLY
TAG: specSize_width = 100 , specSize_height = 100
由此可知
a.当控件的layout_width或layout_height指定为wrap_content时,为AT_MOST
b.当控件的layout_width或layout_height指定为match_parent或具体数值时,为EXACTLY
关于上述1,可能会有些疑问,为什么宽高设置成wrap_content,父控件给该子控件分配了整个屏幕的大小?因为子控件的“android:text”值可能很长,长到占据整个屏幕,此时只要控件的尺寸不超过父控件允许的最大尺寸即可。子控件会在onMeasure方法中判断它的所需尺寸,当所需尺寸 < 屏幕尺寸时,就使用所需尺寸;当所需尺寸 >= 屏幕尺寸时,则使用屏幕尺寸
注意:文章中所说的都是父控件给子控件分配的尺寸