美文网首页Android全集
【Android】MeasureSpec简述

【Android】MeasureSpec简述

作者: littlefogcat | 来源:发表于2021-01-29 08:11 被阅读0次

    在 View 的 onMeasure 回调中,有两个参数widthMeasureSpecheightMeasureSpec,分别代表当前View的宽与高的MeasureSpec

    1. MeasureSpec 的本质

    MeasureSpec 的本质是一个整型值。
    众所周知,Java/Kt 中的整型占用了 32 位;而 MeasureSpec 的前2位表示测量模式(mode),后30位表示测量大小(size),实现了一个整型保存两个信息的目的。

    通过MeasureSpec.getMode(measureSpec)静态方法可以获取一个 MeasureSpec 的 mode,MeasureSpec.getSize(measureSpec)可以获取到 size。

        override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
            val wMode = MeasureSpec.getMode(widthMeasureSpec) // 水平方向的测量模式
            val wSize = MeasureSpec.getSize(widthMeasureSpec) // 水平方向的测量大小
            val hMode = MeasureSpec.getMode(heightMeasureSpec) // 竖直方向的测量模式
            val hSize = MeasureSpec.getSize(heightMeasureSpec) // 竖直方向的测量大小
        }
    

    通过MeasureSpec.makeMeasureSpec(size, mode)静态方法,可以将 mode 与 size 合成为一个 MeasureSpec。

    size 不用多说,表示宽或高的长度,单位是像素。

    mode 分为三种:MeasureSpec.UNSPECIFIEDMeasureSpec.EXACTLYMeasureSpec.AT_MOST;其中,MeasureSpec.UNSPECIFIED基本不用,可以忽视。也就是说,常用的 MeasureSpec 只有EXACTLYAT_MOST两种。
    顾名思义,EXACTLY即为精确模式,表示这个 ViewGroup 的宽或高是确定值size;而AT_MOST则是最大模式,表示这个 View 的宽或高最大能达到size,真实长度根据实际情况而定。

    onMeasure回调中,传入的 MeasureSpec 是根据当前 View 的父容器的 MeasureSpec 和当前 View 在布局中的layout_widthlayout_height 属性决定的。

    2. MeasureSpec 的计算过程

    那么,onMeasure中的两个参数是如何得到的呢?
    事实上,一般来讲,当一个 ViewGroup 测量自身的时候,会先遍历它的子 View,并调用子 View 的measure方法进行测量,而measure方法又会调用onMeasure回调。
    也就是说,View的onMeasure回调方法中的两个参数是父容器计算并传递过来的

    下表反应了正常情况下父容器是如何得到一个子 View 的 MeasureSpec 的。其中横轴表示父容器的 MeasureSpec,纵轴表示了该 View 在布局文件中设置的宽或高,表中为该 View 的 MeasureSpec 的 mode 与 size。

    子View在xml中 \ 父MeasureSpec EXACTLY AT_MOST
    确定的数值 mode: EXACTLY
    size: 布局中设置的大小
    mode: EXACTLY
    size: 布局中设置的大小
    wrap_content mode: AT_MOST
    size: 父容器specSize
    mode: AT_MOST
    size: 父容器specSize
    match_parent mode: EXACTLY
    size: 父容器specSize
    mode: AT_MOST
    size: 父容器specSize

    也就是说:

    1. 当布局中宽或高填写的固定值,那么对应的 mode 为 EXACTLY ,size 为填写的值;
    2. 当布局中的宽或高填写的wrap_content,那么对应的 mode 为 AT_MOST,size 为父容器的 size;
    3. 当布局中的宽或高填写的match_parent,那么顾名思义,mode 和 size 都与父容器相同。

    相关文章

      网友评论

        本文标题:【Android】MeasureSpec简述

        本文链接:https://www.haomeiwen.com/subject/mzvftltx.html