美文网首页
理解MeasureSpec

理解MeasureSpec

作者: 飞翔的超人 | 来源:发表于2019-03-28 06:38 被阅读0次

1.左移和右移

java中的移位运算符有三种:

  • 左移<<
    左移就是将左边的操作数在内存中的二进制数据左移指定的位数,左边移空的部分补零。num << n, 相当于 num 乘以2的 n 次方

  • 右移>>
    右移:右边超出截掉,左边补上符号位 (负的就填1 正的就填0)。num >> n, 相当于 num 除以2的 n 次方

  • 无符号右移>>>
    无符号右移无论最高位是什么,空位都补零

2.MeasureSpec构成

public static int makeMeasureSpec( int size, int mode) {
    if (sUseBrokenMakeMeasureSpec) {
                return size + mode;
            } else {
                return (size & ~MODE_MASK) | (mode & MODE_MASK);
            }
     }  
}    

MeasureSpec其实就是一个32位的int类型值(4个字节32bit),由高2位的mode和低30位的size组成

3.getMode

MeasureSpec有三种mode。UNSPECIFIED , EXACTLY , AT_MOST

        private static final int MODE_SHIFT = 30;
        private static final int MODE_MASK  = 0x3 << MODE_SHIFT;

        /**
         * Measure specification mode: The parent has not imposed any constraint
         * on the child. It can be whatever size it wants.
         */
        public static final int UNSPECIFIED = 0 << MODE_SHIFT;

        /**
         * Measure specification mode: The parent has determined an exact size
         * for the child. The child is going to be given those bounds regardless
         * of how big it wants to be.
         */
        public static final int EXACTLY     = 1 << MODE_SHIFT;

        /**
         * Measure specification mode: The child can be as large as it wants up
         * to the specified size.
         */
        public static final int AT_MOST     = 2 << MODE_SHIFT;

  • UNSPECIFIED = 0 << MODE_SHIFT; 即: 00000000 00000000 00000000 00000000
  • EXACTLY = 1 << MODE_SHIFT; 即: 01000000 00000000 00000000 00000000
  • AT_MOST = 2 << MODE_SHIFT; 即: 10000000 00000000 00000000 00000000
public static int getMode(int measureSpec) {
            //noinspection ResourceType
            return (measureSpec & MODE_MASK);
}

getMode()方法中,MODE_MASK=11000000 00000000 00000000 00000000,将32位的measureSpec和11000000 00000000 00000000 00000000进行&运算,最终得到的肯定是measureSpec的高2位。

比如生成measureSpec时传入AT_MOST。那么measureSpec为10000000 00000000 00000000 00000101,

measureSpec & MODE_MASK 即
10000000 00000000 00000000 00000101
&
11000000 00000000 00000000 00000000
=
10000000 00000000 00000000 00000000
=AT_MOST

传入measureSpec后,measureSpec的低30位肯定全部为0,最终只剩下高2位。而measureSpec的高2位正好就是mode

4.getSize

public static int getSize(int measureSpec) {
            return (measureSpec & ~MODE_MASK);
}

getSize方法原理跟getMode一样,只是先将MODE_MASK取反,
~MODE_MASK=00111111 11111111 11111111 11111111
然后measureSpec和~MODE_MASK进行&运算,结果肯定为measureSpec的低30位了,因为高2位和00进行&运算肯定是00了

5.总结

自定义View时会经常使用到MeasureSpec,通过它拿size或者mode,其实只是生成一个32位的int值,取其高2位或者低30位。提高了运行效率

相关文章

  • 理解MeasureSpec

    4.2 理解MeasureSpec 为了更好地理解View的测量过程,我们还需要理解MeasureSpec。从名字...

  • 理解MeasureSpec

    MeasureSpec在很大程度上决定了一个View的尺寸规格,因为父容器影响View的MeasureSpec的创...

  • 理解MeasureSpec

    MeasureSpec是View的一个静态内部类,它通过将SpecMode和SpecSize打包成一个int值来避...

  • 理解MeasureSpec

    1.左移和右移 java中的移位运算符有三种: 左移<<左移就是将左边的操作数在内存中的二进制数据左移指定的位数,...

  • MeasureSpec 理解

    MeasureSpec 封装了父布局传递给子布局的布局要求,每个MeasureSpec代表了一组宽度和高度的要求 ...

  • MeasureSpec理解

    简要   今天来聊聊MeasureSpec,记得刚接触的也感觉很难理解,知其然不知其所以然。MeasureSpec...

  • Android 理解MeasureSpec

    Android View 的测量过程中使用到了MeasureSpec,正如其字面意思所表达的那个-“测量规格”。V...

  • 简单理解MeasureSpec

    MeasureSpec在很大程度上决定了一个View的尺寸规格,因为父容器影响View的MeasureSpec的创...

  • 4.2 理解MeasureSpec

    1. MeasureSpec MeasureSpec代表一个32位的int值,高2位代表SpecMode,低30位...

  • 重新理解MeasureSpec

    1 概述 网上有许多非常好的文章都在介绍MeasureSpec的测量规则,但是没有介绍MeasureSpec的作用...

网友评论

      本文标题:理解MeasureSpec

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