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);
        }   

Android Measure中对应方法解析

时间: 2024-10-05 17:18:16

Android Measure中对应方法解析的相关文章

Android开发中回调方法的简单应用

"回调/回调方法"这个词语对我们程序员来说肯定不陌生.在Android的学习及开发过程中,我们经常会听到也会用到"回调(回调方法)"这个词,那么什么是回调呢:在类A中定义了一个方法,这个方法中用到了一个接口(Interface)和该接口中的方法,但是这个方法方法没有具体的实现,需要在类B中去实现,类B实现该方法具体业务处理后,再传递给A类,供A类去调用,这种机制就称为回调.A来B去听起来有点拗口,下面我们用个简单的例子来实现. 我们在Activity中定义了一个Li

android操作线程各种方法解析

(一)刚开始学习android的时候我是这么写的 1 new Thread( new Runnable() { public void run() { myView.invalidate(); } }).start(); 后来看到别的博客说这种违反android单线程模型 本人不理解非要刨根问题 那么它是怎么违反单线程模型的呢? 百度了一下找到了原因 如下 一个 Android 程序开始运行时,就有一个主线程Main Thread被创建.该线程主要负责UI界面的显示.更新和控件交互,所以又叫UI

AppDelegate中的方法解析

// 当应用程序启动完毕的时候就会调用(系统自动调用) -(BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions; // 即将失去活动状态的时候调用(失去焦点, 不可交互) -(void)applicationWillResignActive:(UIApplication *)application; // 重新获取焦点(能够和用户交互)

javascript中apply()方法解析-简单易懂!

今天看到了js的call与apply的异同,想着整理一下知识点,发现了一篇好文章,分享过来给大家,写的非常好! 参考: http://www.cnblogs.com/delin/archive/2010/06/17/1759695.html 1.对象的继承,一般的做法是复制:Object.extend prototype.js的实现方式是: Object.extend = function(destination, source) { for (property in source) { des

JS中 isNaN() 方法解析

1. isNaN() 存在的意义 由于 NaN 是唯一一个不等于自身的值,不像其他的值,可以用相等操作符来判断是否等于自身,NaN == NaN和NaN === NaN都会返回false,所以isNaN()就诞生了,那它到底起着怎样的作用呢,且看下文. 2. isNaN() 判断的原理 isNaN函数接受一个参数,原理是先尝试将参数转换为数值型,调用的是Number()方法,再进行判断. 说到这里就有必要介绍一下Number()方法了,其实Number()方法的原理也有点复杂,具体分两种情况.

android编程中setLayoutParams方法设置

第一篇 private LinearLayout generateHeadOfControl() { LinearLayout LayoutHead = createLayout(LinearLayout.HORIZONTAL); Button DateButton = generateDateButton(); Button ItemButton = generateItemButton(); DateButton.setLayoutParams(new LinearLayout.Layout

activity生命周期中方法解析

对于activity的生命周期我觉得是一个简单而又不简单的问题,很多人可能觉得自己已经很精通了!往往事实却不以为然! 要接着讨论下面的问题,先来简单了解一下activity,来看一段原文的说明,如下: An activity is a single, focused thing that the user can do.  Almost all activities interact with the user, so the Activity class takes care of creat

Android WebView中的JavaScript代码使用(转载)

转载来源:http://www.cnblogs.com/mengdd/archive/2013/03/02/2940185.html 本篇文章主要介绍WebView中的JavaScript代码的执行相关,已经JS代码与Android代码的互相调用. (因为本人对Web开发并不是很熟悉,所以如果有哪些地方说得不对,还请指正.) 在WebView中使用JavaScript 如果你想要载入的页面中用了JavaScript,你必须为你的WebView使能JavaScript. 一旦使能之后,你也可以自己

Android中使用Gson解析JSON数据的两种方法

Json是一种类似于XML的通用数据交换格式,具有比XML更高的传输效率;本文将介绍两种方法解析JSON数据,需要的朋友可以参考下 Json是一种类似于XML的通用数据交换格式,具有比XML更高的传输效率. 从结构上看,所有的数据(data)最终都可以分解成三种类型: 第一种类型是标量(scalar),也就是一个单独的字符串(string)或数字(numbers),比如"北京"这个单独的词. 第二种类型是序列(sequence),也就是若干个相关的数据按照一定顺序并列在一起,又叫做数组