`

Android 获取控件的宽高高级用法(MeasureSpec)

 
阅读更多
一个MeasureSpec封装了父布局传递给子布局的布局要求,每个MeasureSpec代表了一组宽度和高度的要求。一个MeasureSpec由大小和模式组成。它有三种模式:UNSPECIFIED(未指定),父元素不对子元素施加任何束缚,子元素可以得到任意想要的大小;EXACTLY(完全),父元素决定子元素的确切大小,子元素将被限定在给定的边界里而忽略它本身大小;AT_MOST(至多),子元素至多达到指定大小的值。
它常用的三个函数:
  1.staticint getMode(int measureSpec):根据提供的测量值(格式)提取模式(上述三个模式之一)
  2.staticint getSize(int measureSpec):根据提供的测量值(格式)提取大小值(这个大小也就是我们通常所说的大小)
  3.staticint makeMeasureSpec(int size,int mode):根据提供的大小值和模式创建一个测量值(格式)

  这个类的使用呢,通常在view组件的onMeasure方法里面调用但也有少数例外,看看几个例子:

  a.首先一个我们常用到的一个有用的函数,View.resolveSize(intsize,int measureSpec)
     public static int resolveSize(int size, int measureSpec) {
         int result = size;
         int specMode = MeasureSpec.getMode(measureSpec);
         int specSize =  MeasureSpec.getSize(measureSpec);
         switch (specMode) {
         case MeasureSpec.UNSPECIFIED:
             result = size;
             break;
         case MeasureSpec.AT_MOST:
             result = Math.min(size, specSize);
             break;
         case MeasureSpec.EXACTLY:
             result = specSize;
             break;
        }
         return result;
     }

再看看MeasureSpec.makeMeasureSpec方法,实际上这个方法很简单:
 public static int makeMeasureSpec(int size, int mode) {
     return size + mode;
 }

这样大家不难理解size跟measureSpec区别了。看看它的使用吧,ListView.measureItem(View child)
     private void measureItem(View child) {
         ViewGroup.LayoutParams p = child.getLayoutParams();
         if (p == null) {
             p = new ViewGroup.LayoutParams(
                     ViewGroup.LayoutParams.MATCH_PARENT,
                     ViewGroup.LayoutParams.WRAP_CONTENT);
         }
 
         int childWidthSpec = ViewGroup.getChildMeasureSpec(mWidthMeasureSpec,
                 mListPadding.left + mListPadding.right, p.width);
         int lpHeight = p.height;
         int childHeightSpec;
         if (lpHeight > 0) {
             childHeightSpec = MeasureSpec.makeMeasureSpec(lpHeight, MeasureSpec.EXACTLY);
         } else {
             childHeightSpec = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED);
         }
         child.measure(childWidthSpec, childHeightSpec);
     }

measureSpec方法通常在ViewGroup中用到,它可以根据模式(MeasureSpec里面的三个)可以调节子元素的大小。
  注意,使用EXACTLY和AT_MOST通常是一样的效果,如果你要区别他们,那么你就要使用上面的函数View.resolveSize(int size,int measureSpec)返回一个size值,然后使用你的view调用setMeasuredDimension(int,int)函数。
     protected final void setMeasuredDimension(int measuredWidth, int measuredHeight) {
         mMeasuredWidth = measuredWidth;
         mMeasuredHeight = measuredHeight;
 
         mPrivateFlags |= MEASURED_DIMENSION_SET;
     }

然后你调用view.getMeasuredWidth,view.getMeasuredHeigth 返回的就是上面函数里的mMeasuredWidth,mMeasuredHeight的值。
分享到:
评论

相关推荐

    android自定义控件-侧滑菜单

    mode共有三种情况,取值分别为MeasureSpec.UNSPECIFIED, MeasureSpec.EXACTLY, MeasureSpec.AT_MOST。 MeasureSpec.EXACTLY是精确尺寸, 当我们将控件的layout_width或layout_height指定为具体数值时如andorid ...

    Android OnCreate()中获取控件高度与宽度两种方法详解

    Android OnCreate()中获取控件高度与宽度 试过在OnCreate()中获取控件高度与宽度的童鞋都知道,getWidth()与getHeight()方法返回是0,具体原因 看一下Activity的生命周期 就会明白。 上代码: 方法一: int w...

    Android MeasureSpec的理解和源码的解析

    Android MeasureSpec的理解和源码的解析 MeasureSpec的创建规则: 实例详解: package cc.ww; import android.view.View; import android.view.View.MeasureSpec; import android.view.ViewGroup.LayoutParams; ...

    Android视图控件架构分析之View、ViewGroup

    在Android中,视图控件大致被分为两类,即ViewGroup和View,ViewGroup控件作为父控件,包含并管理着子View,通过ViewGroup和View便形成了控件树,各个ViewGoup对象和View对象就是控件树中的节点。在控件树中,以树的...

    MeasureSpec三种测量模式详解例子

    MeasureSpec三种测量模式详解例子

    android 实现FlowLayout 流线布局(自定义ViewGroup)

    [Android开发:LayoutParams的用法](http://blog.csdn.net/double2hao/article/details/51438798) [MarginLayoutParams--一个可以在代码中直接设置margin的方法]...

    Android开发艺术探索.任玉刚(带详细书签).pdf

    本书是一本Android进阶类书籍,采用理论、源码和实践相结合的方式来阐述高水准的Android应用开发要点。本书从三个方面来组织内容。第一,介绍Android开发者不容易掌握的一些知识点;第二,结合Android源代码和应用层...

    Android开发艺术探索

    《Android开发艺术探索》是一本Android进阶类书籍,采用理论、源码和实践相结合的方式来阐述高水准的Android应用开发要点。《Android开发艺术探索》从三个方面来组织内容。第一,介绍Android开发者不容易掌握的一些...

    Android酷炫转动菜单

    import android.content.Context; import android.graphics.drawable.Drawable; import android.util.AttributeSet; import android.util.Log; import android.view.LayoutInflater; import android.view....

    Android自定义View

    介绍如何自定义View,并重写onMeasure方法重新测量高度和宽度, 讲解MeasureSpec类的使用方法 详见博文 http://blog.csdn.net/a87b01c14/article/details/50359226

    类似时光网IOS城市列表(ListView)效果.zip

    结构是listview嵌套gridview,需要注意的是gridview需要重写onMeasure方法: @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { int expandSpec = MeasureSpec....

    浅析Android中getWidth()和getMeasuredWidth()的区别

    结论:getMeasuredWidth()获取的是view...这个值是一个8位的十六进制的数字,高两位表示的是这个measure阶段的Mode的值,具体可以查看MeasureSpec的原理。这里mMeasuredWidth & MEASURED_SIZE_MASK表示的是测量阶段结

    Android实现Z轴布局效果

    如果需要在布局中创造一个层叠的概念,那么使用Android系统中的ViewGroup是不够的,但是可以通过改变ViewGroup的绘制顺序实现 代码下载 继承自FrameLayout FrameLayout已经帮我们实现了子View的measure和layout过程,...

    android异步生成图片的示例代码

    下面来说说在Android上如果异步生成图片,通过xml布局用View排版好图片样式,在子线程生成一张图片,以满足生成用来分享的图片等需求(生成图片前设置可变元素,如用户的头像,昵称等)。 效果 点击按钮生成图片: ...

    WelcomeVideoPager-仿蚂蜂窝自由行和慕课网视频欢迎页.zip

     setMeasuredDimension(View.MeasureSpec.getSize(widthMeasureSpec), View.MeasureSpec.getSize(heightMeasureSpec));  }  /**  * 播放视频  *  * @param uri 播放地址  */  public void ...

    仿微信朋友圈图片查看

    import android.content.Context;... int expandSpec = MeasureSpec.makeMeasureSpec(Integer.MAX_VALUE >> 2, MeasureSpec.AT_MOST); super.onMeasure(widthMeasureSpec, expandSpec); } }

    Android开发之自定义CheckBox

    要实现的效果如下 考虑到关键是动画效果,所以直接继承View。不过CheckBox的超类CompoundButton实现了... * A MeasureSpec encapsulates the layout requirements passed from parent to child. * Each MeasureSp

    ViewPager 放大缩小左右移动

    实现 图片的放大,缩小,左右屏幕滑动 。 直接贴代码吧。。 public class ViewPager extends ViewGroup { private static final String TAG = "ViewPager"; private static final boolean DEBUG = false;...

Global site tag (gtag.js) - Google Analytics