zoukankan      html  css  js  c++  java
  • Android Measure中对应方法解析

    注:根据网上资料整理如下

    首先 onMeasure方法是为了得到各个View大小的函数

    fill_parent-->public static final int EXACTLY = 1 << MODE_SHIFT;

    wrap_content-->public static final int AT_MOST = 2 << MODE_SHIFT;

    这是makeMeasureSpec方法的代码片段

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

    其中sUseBrokenMakeMeasureSpec的默认值是false:

    /**
         * Use the old (broken) way of building MeasureSpecs.
         */
        private static boolean sUseBrokenMakeMeasureSpec = false;

    下面看一下sUseBrokenMakeMeasureSpec相关代码

     1     public View(Context context) {
     2     //此处省略无关代码......17 
    18         if (!sCompatibilityDone && context != null) {
    19             final int targetSdkVersion = context.getApplicationInfo().targetSdkVersion;
    20 
    21             // Older apps may need this compatibility hack for measurement.
    22             sUseBrokenMakeMeasureSpec = targetSdkVersion <= JELLY_BEAN_MR1;
    23 
    24             // Older apps expect onMeasure() to always be called on a layout pass, regardless
    25             // of whether a layout was requested on that View.
    26             sIgnoreMeasureCache = targetSdkVersion < KITKAT;
    27 
    28             sCompatibilityDone = true;
    29         }
    30     }

    在构造方法中对sUseBrokenMakeMeasureSpec的值进行了判断,代码走进第18行又出现了一个sCompatibilityDone,

    追溯其值原来默认值是false,所以在view初始化的时候肯定会走进这一行的,当sdk版本小于JELLY_BEAN_MR1也就是4.2的时候会返回true,

    好 现在回头看看也就是说4.2版本或一下makeMeasureSpec返回值是size + mode之后的版本都是(size & ~MODE_MASK) | (mode & MODE_MASK)

    现在说一下MeasureSpec中重要的方法

    // 进位大小为2的30次方(int的大小为32位,所以进位30位就是要使用int的最高位和倒数第二位也就是32和31位做标志位)       
            private static final int MODE_SHIFT = 30;
            // 运算遮罩,0x3为16进制,10进制为3,二进制为11。3向左进位30,就是11 00000000000(11后跟30个0)        
            // (遮罩的作用是用1标注需要的值,0标注不要的值。因为1与任何数做与运算都得任何数,0与任何数做与运算都得0)        
            private static final int MODE_MASK  = 0x3 << MODE_SHIFT;        
            // 0向左进位30,就是00 00000000000(00后跟30个0)        
            public static final int UNSPECIFIED = 0 << MODE_SHIFT;        
            // 1向左进位30,就是01 00000000000(01后跟30个0)        
            public static final int EXACTLY     = 1 << MODE_SHIFT;        
            // 2向左进位30,就是10 00000000000(10后跟30个0)        
            public static final int AT_MOST     = 2 << MODE_SHIFT;        
            /**         
            * 根据提供的size和mode得到一个详细的测量结果         
            */        
            // measureSpec = size + mode;    (注意:二进制的加法,不是10进制的加法!)        
            // 这里设计的目的就是使用一个32位的二进制数,32和31位代表了mode的值,后30位代表size的值        
            // 例如size=100(4),mode=AT_MOST,则measureSpec=100+10000...00=10000..00100
         //注意:最新版的sdk的makeMeasureSpec方法在文章首处,不过看过前文相信理解不难
    public static int makeMeasureSpec(int size, int mode) { return size + mode; } /** * 通过详细测量结果获得mode */ // mode = measureSpec & MODE_MASK; // MODE_MASK = 11 00000000000(11后跟30个0),原理是用MODE_MASK后30位的0替换掉measureSpec后30位中的1,再保留32和31位的mode值。 // 例如10 00..00100 & 11 00..00(11后跟30个0) = 10 00..00(AT_MOST),这样就得到了mode的值 public static int getMode(int measureSpec) { return (measureSpec & MODE_MASK); } /** * 通过详细测量结果获得size */ // size = measureSpec & ~MODE_MASK; // 原理同上,不过这次是将MODE_MASK取反,也就是变成了00 111111(00后跟30个1),将32,31替换成0也就是去掉mode,保留后30位的size public static int getSize(int measureSpec) { return (measureSpec & ~MODE_MASK); }
  • 相关阅读:
    Codeforces 845E Fire in the City 线段树
    Codeforces 542D Superhero's Job dp (看题解)
    Codeforces 797F Mice and Holes dp
    Codeforces 408D Parcels dp (看题解)
    Codeforces 464D World of Darkraft
    Codeforces 215E Periodical Numbers 容斥原理
    Codeforces 285E Positions in Permutations dp + 容斥原理
    Codeforces 875E Delivery Club dp
    Codeforces 888F Connecting Vertices 区间dp (看题解)
    Codeforces 946F Fibonacci String Subsequences dp (看题解)
  • 原文地址:https://www.cnblogs.com/weixiao870428/p/3853532.html
Copyright © 2011-2022 走看看