View测量模式:EXACTLY、AT_MOST、UNSPECIFIED

看了不少自定义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方法中判断它的所需尺寸,当所需尺寸 < 屏幕尺寸时,就使用所需尺寸;当所需尺寸 >= 屏幕尺寸时,则使用屏幕尺寸

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

  • 5
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值