zoukankan      html  css  js  c++  java
  • MeasureSpec介绍

    在自定义ViewViewGroup的时候,我们经常会遇到int型的MeasureSpec来表示一个组件的大小,这个变量里面不仅有组件的尺寸大小,还有大小的模式。


    这个大小的模式,有点难以理解。在系统中组件的大小模式有三种:


    1.精确模式

    在这种模式下,尺寸的值是多少,那么这个组件的长或宽就是多少。


    2.最大模式

    这个也就是父组件,能够给出的最大的空间,当前组件的长或宽最大只能为这么大,当然也可以比这个小。


    3.未指定模式

    这个就是说,当前组件,可以随便用空间,不受限制。


    可能有很多人想不通,一个int型整数怎么可以表示两个东西(大小模式和大小的值),一个int类型我们知道有32。而模式有三种,要表示三种状态,至少得2位二进制位。于是系统采用了最高的2位表示模式。如图:


    最高两位是00的时候表示"未指定模式"。即MeasureSpec.UNSPECIFIED

    最高两位是01的时候表示"'精确模式"。即MeasureSpec.EXACTLY

    最高两位是11的时候表示"最大模式"。即MeasureSpec.AT_MOST


    很多人一遇到位操作头就大了,为了操作简便,于是系统给我提供了一个MeasureSpec工具类。

    这个工具类有四个方法和三个常量(上面所示)供我们使用:


    //这个是由我们给出的尺寸大小和模式生成一个包含这两个信息的int变量,这里这个模式这个参数,传三个常量中的一个。

    public static int makeMeasureSpec(int size, int mode)


    //这个是得到这个变量中表示的模式信息,将得到的值与三个常量进行比较。

    public static int getMode(int measureSpec)


    //这个是得到这个变量中表示的尺寸大小的值。

    public static int getSize(int measureSpec)


    //把这个变量里面的模式和大小组成字符串返回来,方便打日志

     public static String toString(int measureSpec)


    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    public static class MeasureSpec {
           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;
     
           /**
            * Creates a measure specification based on the supplied size and mode.
            *
            * The mode must always be one of the following:
            * <ul>
            *  <li>{@link android.view.View.MeasureSpec#UNSPECIFIED}</li>
            *  <li>{@link android.view.View.MeasureSpec#EXACTLY}</li>
            *  <li>{@link android.view.View.MeasureSpec#AT_MOST}</li>
            * </ul>
            *
            * <p><strong>Note:</strong> On API level 17 and lower, makeMeasureSpec's
            * implementation was such that the order of arguments did not matter
            * and overflow in either value could impact the resulting MeasureSpec.
            * {@link android.widget.RelativeLayout} was affected by this bug.
            * Apps targeting API levels greater than 17 will get the fixed, more strict
            * behavior.</p>
            *
            * @param size the size of the measure specification
            * @param mode the mode of the measure specification
            * @return the measure specification based on size and mode
            */
           public static int makeMeasureSpec(int size, int mode) {
               if (sUseBrokenMakeMeasureSpec) {
                   return size + mode;
               } else {
                   return (size & ~MODE_MASK) | (mode & MODE_MASK);
               }
           }
     
           /**
            * Extracts the mode from the supplied measure specification.
            *
            * @param measureSpec the measure specification to extract the mode from
            * @return {@link android.view.View.MeasureSpec#UNSPECIFIED},
            *         {@link android.view.View.MeasureSpec#AT_MOST} or
            *         {@link android.view.View.MeasureSpec#EXACTLY}
            */
           public static int getMode(int measureSpec) {
               return (measureSpec & MODE_MASK);
           }
     
           /**
            * Extracts the size from the supplied measure specification.
            *
            * @param measureSpec the measure specification to extract the size from
            * @return the size in pixels defined in the supplied measure specification
            */
           public static int getSize(int measureSpec) {
               return (measureSpec & ~MODE_MASK);
           }
     
           static int adjust(int measureSpec, int delta) {
               return makeMeasureSpec(getSize(measureSpec + delta), getMode(measureSpec));
           }
     
           /**
            * Returns a String representation of the specified measure
            * specification.
            *
            * @param measureSpec the measure specification to convert to a String
            * @return a String with the following format: "MeasureSpec: MODE SIZE"
            */
           public static String toString(int measureSpec) {
               int mode = getMode(measureSpec);
               int size = getSize(measureSpec);
     
               StringBuilder sb = new StringBuilder("MeasureSpec: ");
     
               if (mode == UNSPECIFIED)
                   sb.append("UNSPECIFIED ");
               else if (mode == EXACTLY)
                   sb.append("EXACTLY ");
               else if (mode == AT_MOST)
                   sb.append("AT_MOST ");
               else
                   sb.append(mode).append(" ");
     
               sb.append(size);
               return sb.toString();
           }
       }


     



  • 相关阅读:
    Java tomcat max-http-header-size配置导致的oom
    Idea修改jvm参数
    Java List的SubList使用问题
    Java Arrays.asList的三个坑
    Java 重写equals的时候为什么一定要重写hashcode-一个例子
    远心镜头
    镜头常识总结
    halcon中保存图像jpeg的压缩比
    红外光 相机拍照
    电磁波的穿透能力总结
  • 原文地址:https://www.cnblogs.com/Cyning/p/3530168.html
Copyright © 2011-2022 走看看