Android对ViewGroup中OnMeasure方法的一些个人见解

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

       首先说说这个这个函数,函数功能可能搞过自定义View的小伙伴们都知道这个函数是干吗用的,就是用来测量当前View大小的一个函数,函数功能大家可能都非常明白,可是对于如何去重载这个方法(如何自己去实现一个有效果的测量过程)很多人不是非常明白,包括我自己,所以我花了一天的时间去琢磨这个东西,终于悟出了一点门道,现在和大家做分享,对于博客中提出的笔者也尚未明确点也希望高手指点迷津.

先来说说这两个函数的参数的意思,这是两个Int型的变量,但是这不是两个普通的int型参数,这个参数其实是由2个其他参数经过某种运算合成出来的一个Int型参数,一个是Size,一个是Mode,其中Mode分为三种模式:EXACTLY, AT_MOST, UNSPECIFIED.下面我将详细的说明这三种模式的不同之处(经过反复试验验证),不过在此之前我们先来看看这两个参数是如何“加密”成一个参数的,又如何对其进行“解密”。

对Mode和Size进行加解密都是在一个叫MeasureSpec类中进行的,所涉及到的函数有3个:

1:makeMeasureSpec(int size, int mode)Creates a measure specification based on the supplied size and mode.

传入2个参数,1个size一个mode然后通过某种运算返回一个合成后的Int型参数 measureSpec

2:getMode(int measureSpec)Extracts the mode from the supplied measure specification.

传入一个measureSpec参数,分离出其中的Mode

3: getSize(int measureSpec)Extracts the size from the supplied measure specification.

传入一个measureSpec参数,分离出其中的size.

下面我来说说size和mode这2个参数,size就是大小,什么的大小呢?其实就是系统的布局分配算法分配给当前ViewGroup的像素大小,mode是用来指定当前的ViewGroup以何种模式去获得分配空间大小用的。

光用语言说比较生硬,下面看个例子:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent" >

    <net.ting.sliding.SlideMenu
        android:id="@+id/slide_menu"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content" >
        
    </net.ting.sliding.SlideMenu>

</RelativeLayout>
这是一个简单的自定义控件的xml文件,我们假定当前View是SlideMenu,一下简称S,可以看到他的父控件是一个RelativeLayout ,以下简称R,我们先单独分析宽度,调用getMode和getSize将R传递给S的 widthMeasureSpec参数进行分解(即在S中重载OnMeasure函数中的参数 widthMeasureSpec),有以下几种情况:

1:当R是layout_width="fill_parent"时,S是wrap_content时,R调用S的OnMeasure函数是传入的参数经过分解得到的结果是mode为AT_MOST, size为屏幕的分辨率的宽。

2:当R的layout_width="500dp"时,S依然是wrap_content时,R调用S的OnMeasure函数是传入的参数经过分解得到的结果是mode为AT_MOST, size为750px(在我的手机上进行换算正好是500dp).

3:当R的layout_width="fill_parent"时,S也是fill_parent时,R调用S的OnMeasure函数是传入的参数经过分解得到的结果是mode为EXACTLY, size为屏幕的分辨率的宽.

4:当R的layout_width="500dp"时,S是fill_parent时,R调用S的OnMeasure函数是传入的参数经过分解得到的结果是mode为EXACTLY, size为750px(在我的手机上进行换算正好是500dp).

/**************************************************时间原因,暂时待续*******************************************************/

先把结论记录一下:

EXACTLY是指给当前View分配的显示空间是一个具体的数值,size是多大View的显示空间就是多大,而至于View控件的大小是依赖于该控件的layout_width和layout_height的值(这里要搞清楚2个概念,View的尺寸的大小和View的显示空间的大小,假如一个Button的尺寸是1000dp,1000dp。而他的父控件只能给他100dp,100dp的显示空间大小,那么这个Button就会显示不全,只能显示一部分,但是这个Button的实际大小还是1000dp,1000dp)。

AT_MOST是父控件告诉子View你最大不能超过多大,如果子View的大小没有超过AT_MOST模式下的size值,那么子View的大小就是wrap_content时候的大小,如果超过size的值,那么View的显示空间大小就是size

UNSPECIFIED是父控件不限制子控件的显示空间大小,子控有多大就分配多大的显示空间,这个时候注意子控件“想要多大”和“有多大”是有区别的,想要多大的是通过配置当前View的layout_width和layout_height来像View的父控件表达自己的需求,希望父控件能给他什么样的显示空间,而有多大是当前View的子控件在wrap_content的情况下最小的控件大小是多少。UNSPECIFIED的意思就是你View控件有多大我给你多大的空间,而AT_MOST会对分配给View的空间大小做一个限制,限制你最大不能超过多少(这个值是由size来指定的),而且size指最大不会超过屏幕的像素指,指定一个超过像素最大值得size系统会默认将size大小设置为像素最大值。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值