protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {...




    
}

可以看到,它的参数是widthMeasureSpec与heightMeasureSpec两个int值。这两个参数实质上是由View的静态内部类MeasureSpec管理的两个特殊的“对象”(并非真正的对象),包含了父view关于子view应当如何测量自身给出的 “指示” 。为了提升效率,Android系统采用位运算的方式,将模式SpecMode(2位)与尺寸SpecSize(30位)拼接成了一个int值,并传递这个int值作为测量时使用的参数。
MeasureSpec类的实现基本都是依靠位运算,没什么实质性内容。直接上一些结论:
(1)SpecMode分三种:UNSPECIFIED、EXACTLY、AT_MOST。UNSPECIFIED表示不指定具体测量模式,EXACTLY表示父View希望子view的尺寸取精确值(即等于SpecSize),AT_MOST表示父View希望子view的尺寸不超过SpecSize。
(2)使用MeasureSpec.getMode(int measureSpec)与MeasureSpec.getSize(int measureSpec)获取SpecMode与SpecSize。
(3)使用MeasureSpec.makeMeasureSpec(int size,int mode)生成一个measureSpec值。

onMeasure(int widthMeasureSpec, int heightMeasureSpec)方法

下面回到onMeasure()方法。顾名思义,这个方法是在该view需要测量自身时调用的。具体来说,当这个view的父view对其调用measure()方法时,onMeasure()方法会在过程中被调用。下面分别看看View与ViewGroup分别应当怎么实现这个方法。

View的onMeasure()实现

view只需要根据自身情况,计算出自己的尺寸就可以了。步骤如下:
(1)使用MeasureSpec.getMode()与MeasureSpec.getSize()获取父view要求的SpecMode与SpecSize。
(2)根据上面的参数确定自己的实际尺寸(width与height)。一般来说,如果SpecMode是EXACTLY,那么直接取尺寸值=SpecSize即可。如果SpecMode是AT_MOST,那么就需要根据自身特点计算出一个尺寸值,并保证最终尺寸值不超过SpecSize。当然了,你也可以完全无视父view的要求,自顾自地进行测量,不过这种方式显然是不推荐的。
(3)使用setMeasuredDimension(int measuredWidth, int measuredHeight)设置最终测量尺寸。这个方法被调用之后,view的getMeasuredWidth()方法与getMeasuredHeight()方法才能生效(在之前调用会返回0)。
实际上,对于不那么复杂的自定义view,View类提供的默认实现已经可以满足大部分需求了。下面看看它是怎么做的:

protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
    setMeasuredDimension(
    getDefaultSize(getSuggestedMinimumWidth(), widthMeasureSpec),
    getDefaultSize(getSuggestedMinimumHeight(), heightMeasureSpec));

getSuggestedMinimumWidth()与getSuggestedMinimumHeight()是根据view是否设置了BackgroundDrawable确定一个最小尺寸值。重点看一下getDefaultSize()方法:

public static int getDefaultSize(int size, int measureSpec) {
//size是view根据自身需求提供的一个尺寸值,measureSpec来自父view。
    //最终尺寸值
    int result = size;
    //获取父布局要求的测量模式与测量尺寸
    int specMode = MeasureSpec.getMode(measureSpec);
    int specSize = MeasureSpec.getSize(measureSpec);
    switch (specMode) {
    //如果模式为UNSPECIFIED则不作限制
    case MeasureSpec.UNSPECIFIED:
        result = size;
        break;
    //AT_MOST直接当做EXACTLY处理
    case MeasureSpec.AT_MOST:
    //如果模式为EXACTLY,则根据父布局要求确定最终尺寸值
    case MeasureSpec.EXACTLY:
        result = specSize;
        break;
    return result;

解释见代码注释。这里需要记住的是,如果使用这个方法计算尺寸值的话,AT_MOST模式不会生效。AT_MOST一般是在view的layout_width与layout_height为WRAP_CONTENT时使用的。因此,如果想要自定义view支持WRAP_CONTENT属性,就必须自己对AT_MOST的情况作出处理。

ViewGroup的onMeasure()实现

不同于View,ViewGroup需要负责子view的测量。具体来讲,就是为子view提供合适的MeasureSpec,并调用子view的measure()(注意,不是onMeasure())方法。至于自身的尺寸,则需要结合更高一层的父view的指示以及子view的情况来确定。
为了给子view提供合适的MeasureSpec,ViewGroup中提供了一个getChildMeasureSpec()方法,下面看看它的实现:

public static int getChildMeasureSpec(int spec, int padding, int childDimension) {
    int specMode = MeasureSpec.getMode(spec);
    int specSize = MeasureSpec.getSize(spec);
    int size = Math.max(0, specSize - padding);
    int resultSize = 0;
    int resultMode = 0;
    switch (specMode) {
    // Parent has imposed an exact size on us
    case MeasureSpec.EXACTLY:
        if (childDimension >= 0) {
            resultSize = childDimension;
            resultMode = MeasureSpec.EXACTLY;
        } else if (childDimension == LayoutParams.MATCH_PARENT) {
            // Child wants to be our size. So be it.
            resultSize = size;
            resultMode = MeasureSpec.EXACTLY;
        } else if (childDimension == LayoutParams.WRAP_CONTENT) {
            // Child wants to determine its own size. It can't be bigger than us.
            resultSize = size;
            resultMode = MeasureSpec.AT_MOST;
        break;
    // Parent has imposed a maximum size on us
    case MeasureSpec.AT_MOST:
        if (childDimension >= 0) {
            // Child wants a specific size... so be it
            resultSize = childDimension;
            resultMode = MeasureSpec.EXACTLY;
        } else if (childDimension == LayoutParams.MATCH_PARENT) {
            // Child wants to be our size, but our size is not fixed.
            // Constrain child to not be bigger than us.
            resultSize = size;
            resultMode = MeasureSpec.AT_MOST;
        } else if (childDimension == LayoutParams.WRAP_CONTENT) {
            // Child wants to determine its own size. It can't be bigger than us.
            resultSize = size;
            resultMode = MeasureSpec.AT_MOST;
        break;
    // Parent asked to see how big we want to be
    case MeasureSpec.UNSPECIFIED:
        if (childDimension >= 0) {
            // Child wants a specific size... let him have it
            resultSize = childDimension;
            resultMode = MeasureSpec.EXACTLY;
        } else if (childDimension == LayoutParams.MATCH_PARENT) {
            // Child wants to be our size... find out how big it should be
            resultSize = View.sUseZeroUnspecifiedMeasureSpec ? 0 : size;
            resultMode = MeasureSpec.UNSPECIFIED;
        } else if (childDimension == LayoutParams.WRAP_CONTENT) {
            // Child wants to determine its own size.... find out how big it should be
            resultSize = View.sUseZeroUnspecifiedMeasureSpec ? 0 : size;
            resultMode = MeasureSpec.UNSPECIFIED;
        break;
    //noinspection ResourceType
    return MeasureSpec.makeMeasureSpec(resultSize, resultMode);

英文注释是自带的,已经很详细了。参数spec是高层view提供的MeasureSpec,padding为需要扣除的padding部分尺寸,childDimension为子view需求的尺寸(一般直接传MarginLayoutParams.width)。实质上,这个方法就是综合考虑了高层view的指示以及低层view的需求,分9种情况构建了一个合适的MeasureSpec。下面的图来自Android View系统解析(下) ,任玉刚总结

关于onMeasure()方法的实现差不多就这些内容了。可以看出,MeasureSpec是父view与子view沟通的桥梁。实现onMeasure()方法的关键点就在于如何响应父view的MeasureSpec,以及如何为子view构建合适的MeasureSpec。

转载请标明出处:http://blog.csdn.net/xmxkf/article/details/51468648本文出自:【openXu的博客】目录:onMeasure什么时候会被调用onMea... 来自: openXu的专栏      在开始本篇的正文之前,请允许我先粗略的解释一下MeasureSpec的作用,对本篇的理解会有帮助,但是关于View绘制的流程,本篇暂时不多做介绍了,对View的绘制流程还不是很熟悉的同学,请... 来自: 生死看淡_不服就干的博客 前言转载请注明出处!这类的文章很多很多,其实我也是不想写的.但是说起来我虽然看了很多很多的文章,但是对于View控件的measure方法还是一知半解的.那么今天我就来做一个总结,并且解决很多人问我的一... 来自: 小金子的专栏 http://blog.csdn.net/cyp331203/article/details/45027641     自定义view/viewgroup要重写的几个方法:onMeasure(),on... 来自: 咸鱼吐泡的专栏 Android开发中偶尔会用到自定义View,一般情况下,自定义View都需要继承View类的onMeasure方法,那么,为什么要继承onMeasure()函数呢?什么情况下要继承onMeasure... 来自: tuke_tuke的博客 前言玩过自定义View的小伙伴都知道,在View的绘制过程中,有一个类叫做Path,Path可以帮助我们实现很多自定义形状的View(总有奇葩View等着我们),特别是配合xfermode属性来使用的... 来自: 递归安卓 一、Https基础   1、Http的缺点       1)、通信报文是明文,内容容易被窃听       2)、没有通信方的身份,通信方容易被伪装       3)、无法验证报文的完整性,因此内容可能... 来自: walk的博客 作用:根据父容器传递跟子容器的大小要求来确定子容器的大小。protectedvoidonMeasure(intwidthMeasureSpec,intheightMeasureSpec)的参数说明和M... 来自: chuyouyinghe的专栏 View在屏幕上显示出来要先经过measure(计算)和layout(布局).1、什么时候调用onMeasure方法?    当控件的父元素正要放置该控件时调用.父元素会问子控件一个问题,“你想要用多... 来自: 到达的专栏 1:需求分析先上图看效果a:拍照时,中间的拍照按钮稍微小些,单击可以拍照,长按时中间的拍照按钮变大,并有进度提示拍摄视频进度b:中间区域可以手势缩放,单击时可以根据该点进行拍摄/拍照对焦,界面上显示对... 来自: u012216274的博客 在Android中,我们有四种方式来实现视频的播放:1、使用其自带的播放器。指定Action为ACTION_VIEW,Data为Uri,Type为其MIME类型。2、使用VideoView来播放。在布... 来自: WangShuo的专栏 在做查询数据库操作时,报了以上错误,原因是MySQL的max_allowed_packet设置过小引起的,我一开始设置的是1M,后来改为了20Mmysql根据配置文件会限制server接受的数据包大小... 来自: 你本来就很二的博客 View的绘制和事件处理是两个重要的主题,之前说过View的事件分发处理机制,如果还不太清楚的同学可以先看一下AndroidTouch事件的传递机制,这里不再多说了。对于一些系统自带控件实现不了的功能... 来自: 论一个程序员的自我修养 View的工作原理之测量过程目录1.详细测量过程1.1测量过程到底要测量什么?1.2详细过程说明1.3测量概念说明1.3.1测量的是ViewGroup的宽高,不是内容的宽高1.3.2测量的是View的... 来自: Ung8023 在做查询数据库操作时,报了以上错误,还有outofmemeryheaphacp,原因是mysql的max_allowed_packet设置过小引起的,我一开始设置的是1M,后来改为了20Mmysql根... 来自: fly0744的专栏 我在写程序时将图片存入数据库时出现Packetforqueryistoolarge(8129741>4194304).Youcanchangethisvalueontheserverby... 来自: clmmei_123的博客 通过自定义View,我们可以画出一些简单的图形并进行应用。上一篇中我讲了自己对onDraw()方法的一些理解和运用,今天就来讲讲onMeasure()和onLayout()两个方法的理解和使用。... 来自: shan286的专栏 protectedvoidonMeasure(intwidthMeasureSpec,intheightMeasureSpec){setMeasuredDimension(measureWH(widt... 来自: 按时吃饭 写一个自定义控件,只写了onDraw方法,在XML文件中使用,设置宽高为wrap_content,发现在canvas上画的内容很少,但canvas占的空间是整个屏幕,其它控件被覆盖了,因为对自定义控件... 来自: yangshuangyue的博客 问题描述昨天在写一个自定义控件的时候遇到一个问题,就是我通过addView(Viewchild)方法添加View之后再7.0上没有显示出来,6.0上没有问题。通过AS自带的LayoutInspecto... 来自: 蜗牛学开车的博客 1.自定义View常用方法执行顺序1.创建MyView继承ViewpublicclassMyViewextendsView{publicMyView(Contextcontext,@NullableA... 来自: yxxcrliweifeng的博客 背景理解MeasureSpecMeasureSpec情况分析结合图例分析总结Alittlebitofprogresseveryday!Comeon!背景首先关于自定义view的实现过程我这里就不去实现... 来自: 邹奇健身已上瘾  在Android开发中往往需要根据需求对原生控件进行自定义,其中主要涉及到的就是onMeasure,onLayout和onDraw三个方法的重写与使用,其中onMeasure是其中最复杂的一个方法,... 来自: qq_36120901的博客 当进行自定义view时我们首先需要知道这个view的大小,在android中是通过onMeasure来进行测量的,在看《android群英传》后记录学习过程。在自定义view时我们需要重写onMeas... 来自: ostracod 参考:Android自定义View(三、深入解析控件测量onMeasure)onMeasure方法是由父控件调用的,所有父控件都是ViewGroup的子类,ViewGroup是一个抽象类,它里面有一个... 来自: 火星男孩的分享空间 在项目开发中,可能经常遇到嵌套ListView、ScrollView的问题,百度一搜,都是现成的代码,而且都是一样的,就是重写onMeasure方法,但是为什么要那么写,估计就没多少人知道了,这里进行... 来自: Vegetable的博客 自定义View之onMeasure()(一) 在自定义View中,常常碰见onMeasure(),onLayout(),onDraw()三个方法,还有onTouchEvent(),可以构建我们想要实现... 来自: 所谓简爱的博客 在自定义View时重写onDraw方法是为了绘制控件或者UI,而要想能在布局文件中正确的使用,往往还需要重写onMeasure方法计算位置,要想计算位置就得先测量自身的尺寸大小。... 来自: 最美不过,心中有梦,身旁有你! 在自定义view的时候,其实很简单,只需要知道3步骤:1.测量——onMeasure():决定View的大小2.布局——onLayout():决定View在ViewGroup中的位置3.绘制——onD... 来自: Robin Hu的专栏 在很多自定义view之后,控件的高度需要自适应,即使使用wrap_content没有作用还是match_parent的效果,这时就需要重写onMeasure()方法来实现,view类的onMeasur... 来自: mxiaoyem的博客 onmeasure是测量的意思,由系统来调用,在onlayout(布局之前调用)。每个view都会有从 onmeasure->onlayout->onDraw的过程。测量布局然后画出来。这些方法也由各... 来自: u011379141的专栏 全栈工程师开发手册(作者:栾鹏)安卓教程全解安卓自定义view全解安卓自定义view在本文的示例中,我们使用view基类的基本函数进行了属性设置,在onDraw函数中使用Canvas进行绘图,在onM... 来自: 全栈工程师开发手册(原创) View是在Activity中使用到的,所以在自定义View的时候,我们需要了解Activity生命周期方法和View的生命周期方法调用先后顺序。见如下图(1)在ActivityonCreate方法中... 来自: lue2009的专栏 最近写了一个android上chart和table控件,总结了几点关于自定义控件注意点。1.onLayout和onMeasure必须重载。2.如果你无法判断自己的大小,在onMeasure的时候只需要... 来自: iteye_16787的博客 在自定义控件的过程中,系统在绘制View前,必须对View进行测量,已使后面的onLayout(设置View的放置位置)能够顺利进行。而对VIew的测量的过程则是在onMeasure()中进行的。可能... 来自: gongzhiyao37390814的博客 上一篇文章详细讲解了一下onMeasure/measure方法在Android自定义控件时的原理和作用,参看博文:Android自定义控件系列七:详解onMeasure()方法中如何测量一个控件尺寸(... 来自: 苦咖啡的自留地 onMeasure方法设置宽高相等我们在测量的时候去判断然后控制宽高一致  @Override  protectedvoidonMeasure(intwidthMeasureSpec,intheigh... 来自: wujiu59 刚开始以为是变量被初始化了,发现还在;然后开始调试,发现onDraw方法没有执行,因为比较少用,所以就开始查资料,有说必须设置this.setWillNotDraw(false);,但是添加了,也还是... 来自: 我的博客 可以说重载onMeasure(),onLayout(),onDraw()三个函数构建了自定义View的外观形象。再加上onTouchEvent()等重载视图的行为,可以构建任何我们需要的可感知到的自定... 来自: u012604322的专栏 2014-10-29阅读189 评论0android中自定义View时经常会需要重写View的onMeasure(),onLayout()和onDraw()方法,下面分别介绍下这三个方法。一、onMe... 来自: zhaoweixing1989的专栏 排序算法在算法中占着很重要的地位,很多算法的实现都是基于排序算法的(如搜索算法和合并算法)。所以排序算法也是笔试面试中必考内容。但是不管他怎么考,也就是那几种算法,一般不会超出我接下来要讲的这11种,... 1. 前言 隐马尔科夫HMM模型是一类重要的机器学习方法,其主要用于序列数据的分析,广泛应用于语音识别、文本翻译、序列预测、中文分词等多个领域。虽然近年来,由于RNN等深度学习方法的发展,HMM模型... 来自: tostq的专栏 功能点:轮播;列表,下拉刷新上拉加载更多;地图;网络请求;数据绑定等 文本仿照了 找事吧app 附近三公里功能,并感谢找事吧数据的提供。考虑到数据的私密性,本文贴出的代码并没有贴出请求URL,敬... 来自: 阿东 bsgs算法,又称大小步算法(某大神称拔山盖世算法)。 主要用来解决   A^x=B(mod C)(C是质数),都是整数,已知A、B、C求x。(poj 2417 Discrete Lo... 来自: clover_hxy的博客 从百度里边搜到的常规解决方法都是说什么防火墙影响,nat方式本来就ping不通等,今天我记录一个解决方案,不一定适用于所有的情况,但是最起码我的问题解决了。   我的虚拟机版本是12,虚拟机中的wi... 来自:  啸林  nginx是个好东西,Nginx (engine x) 是一个高性能的HTTP和反向代理服务器,也是一个IMAP/POP3/SMTP服务器。Nginx是由伊戈尔·赛索耶夫为俄罗斯访问量第二的Rambl... 来自: maoyuanming0806的博客 安装: yum install qemu 创建image文件: qemu-img create -f qcow2 guest.qcow2 3G 安装linux: 1)下载一个镜像文件,http:... 来自: 务远的博客 本篇文章是根据我的上篇博客,给出的改进版,由于时间有限,仅做了一个简单的优化。相关文章:将excel导入数据库2018年4月1日,新增下载地址链接:点击打开源码下载地址十分抱歉,这个链接地址没有在这篇... 来自: Lynn_Blog 问题场景描述整个项目通过Maven构建,大致结构如下: 核心Spring框架一个module spring-boot-base service和dao一个module server-core 提供系统... 来自: 开发随笔 前段时间看了一些关于LSTM方面的论文,一直准备记录一下学习过程的,因为其他事儿,一直拖到了现在,记忆又快模糊了。现在赶紧补上,本文的组织安排是这样的:先介绍rnn的BPTT所存在的问题,然后介绍最初... 来自: 天道酬勤,做一个务实的理想主义者 我们可能经常会用到这一功能,比如有时,我们不希望用户没有进行登录访问后台的操作页面,而且这样的非法访问会让系统极为的不安全,所以我们常常需要进行登录才授权访问其它页面,否则只会出现登录页面,当然我的思... 来自: 沉默的鲨鱼的专栏 互联网+的影响力就是大,storm框架最初是设计用来做互联网文本处理和一些统计工作的工具,架着互联网的东风越来越多的被大家使用。在一些场合,特别是在已经用了storm架构以后想再用EPL语句,stor... 来自: happynyear的博客 错误类型及描述: expdp 导出表在表分析是开始出现报错。 ORA-39127: unexpected error from call to export_string :=SYS.DBMS_A... 一、概述最近在springboot项目引入thymeleaf模板时,使用非严格标签时,运行会报错。默认thymeleaf模板对html5标签是严格检查的。二、在项目中加NekoHTML库在Maven中... 来自: Luck_ZZ的博客 Aura 是为HTML Canvas提供的混合框架,是适用于 Chrome 和 ChromeOS 的新一代窗口管理器和Shell环境,是Chrome下一个里程碑的框架。此框架的目标是构造具有现代兼容性... 来自: Chrome 官方博客 使用SSM(Spring、SpringMVC和Mybatis)已经有三个多月了,项目在技术上已经没有什么难点了,基于现有的技术就可以实现想要的功能,当然肯定有很多可以改进的地方。之前没有记录SSM整合... 来自: 在路上 Coder__CS:[reply]lagoon_lala[/reply] https://forum.unity.com/threads/unity-5-3-simple-multiplayer-game-tutorial.390812/

Unity官方教程 联机部分翻译 lagoon_lala:请问这个官网原教程的链接是什么?

关于补零扩展与补符号位扩展 weixin_43249053:不对啊,首先127的原码,可能是你打错了111 1111。 127是正数,所以在计算机中储存的格式就是原码0111 1111。