View测量模式:EXACTLY、AT_MOST、UNSPECIFIED

来源:互联网 发布:程序员的修真小说 编辑:程序博客网 时间:2023/09/28 01:59

看了不少自定义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_MOSTTAG: specSize_width = 720 , specSize_height = 1280

2.当将layout_width和layout_height都设置成match_parent

TAG: specMode_width = EXACTLY , specMode_height = EXACTLYTAG: specSize_width = 720 , specSize_height = 1280

3.当将layout_width和layout_height都设置成100px

TAG: specMode_width = EXACTLY , specMode_height = EXACTLYTAG: 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方法中判断它的所需尺寸,当所需尺寸 < 屏幕尺寸时,就使用所需尺寸;当所需尺寸 >= 屏幕尺寸时,则使用屏幕尺寸

注意:文章中所说的都是父控件给子控件分配的尺寸

1 0