`
zsg88
  • 浏览: 25386 次
  • 性别: Icon_minigender_1
  • 来自: 北京
文章分类
社区版块
存档分类
最新评论

MeasureSpec介绍及使用详解

 
阅读更多

  一个MeasureSpec封装了父布局传递给子布局的布局要求,每个MeasureSpec代表了一组宽度和高度的要求。一个MeasureSpec由大小和模式组成。它有三种模式:UNSPECIFIED(未指定),父元素不对子元素施加任何束缚,子元素可以得到任意想要的大小;EXACTLY(完全),父元素决定自元素的确切大小,子元素将被限定在给定的边界里而忽略它本身大小;AT_MOST(至多),子元素至多达到指定大小的值。

  它常用的三个函数:
  1.static int getMode(int measureSpec):根据提供的测量值(格式)提取模式(上述三个模式之一)
  2.static int getSize(int measureSpec):根据提供的测量值(格式)提取大小值(这个大小也就是我们通常所说的大小)
  3.static int makeMeasureSpec(int size,int mode):根据提供的大小值和模式创建一个测量值(格式)

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

     a.首先一个我们常用到的一个有用的函数,View.resolveSize(int size,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值,那自然表示这个函数通常是在onMeasure方法里面调用的。简单说一下,这个方法的主要作用就是根据你提供的大小和模式,返回你想要的大小值,这个里面根据传入模式的不同来做相应的处理。

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

   ViewGroup.getChildMeasureSpec(int spec, int padding, int childDimension)
   计算MeasureSpec然后传递到特定的子视图,此方法用来计算一个合适子视图的尺寸大小(宽度或者高度),
   此方法的目的在于结合我们从子视图的LayoutParams所给出的MeasureSpec信息来获取最合适的结果。
   比如,如果这个View知道自己的大小尺寸(因为它本身的MeasureSpec的model为Exactly,)并且子视图的大小恰好跟父窗口一样大,父窗口必须用给定的大小去layout子视图
   参数:

           spec 父窗口传递给子视图的大小和模式
           padding 父窗口的边距,也就是xml中的android:padding
           childDimension 子视图想要绘制的准确大小,但最终不一定绘制此值

  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的值。

 

分享到:
评论

相关推荐

    MeasureSpec三种测量模式详解例子

    在这个详解例子中,我们将深入探讨MeasureSpec的三种测量模式以及它们如何影响Android UI布局。 1. **UNSPECIFIED模式** UNSPECIFIED模式是最宽松的模式,它表示父视图不对子视图有任何尺寸上的限制。子视图可以...

    Android MeasureSpec的理解和源码的解析

    例如,在LinearLayout中,可以使用MeasureSpec来控制子View的尺寸和布局。 五、MeasureSpec源码解析 Android的MeasureSpec源码位于Android SDK的android.view.View.MeasureSpec.java文件中,该文件定义了...

    Android UI绘制流程及原理详解

    Android UI绘制流程及原理详解 Android UI绘制流程及原理是 Android 应用程序的核心部分,它负责将用户界面元素绘制到屏幕上。在本篇文章中,我们将详细介绍 Android UI绘制流程及原理,并对相关知识点进行解释。 ...

    View坐标位置XY轴详解

    本文将深入探讨“View坐标位置XY轴详解”,并基于配套博客提供的详细内容进行阐述。 首先,我们要知道Android中的坐标系统是基于左上角为原点(0,0)的二维平面。X轴水平向右延伸,Y轴垂直向下延伸。这是与数学中的...

    Android View 的onMeasure方法详解和例子解释

    Log.i("SendView", "widthMode, heightMode: " + MeasureSpec.toString(widthMeasureSpec) + ", " + MeasureSpec.toString(heightMeasureSpec)); setMeasuredDimension(width, height); } ``` 在这个例子中,...

    android自定义viewGroup仿Scrollview详解

    最后,为了提供更好的滚动体验,你还可以考虑实现一些额外的功能,比如滚动动画、滚动边界检测以及与nested滚动的兼容(如果需要在NestedScrollView中嵌套使用)。 在实际项目中,你可以创建一个名为`...

    ListView嵌套GridView使用详解及注意事项

    int heightMeasureSpecCustom = MeasureSpec.makeMeasureSpec(Integer.MAX_VALUE >> 2, MeasureSpec.AT_MOST); super.onMeasure(widthMeasureSpec, heightMeasureSpecCustom); setMeasuredDimension...

    第三章:Android控件架构和自定义控件详解.md

    ### Android控件架构和自定义控件详解 #### 一、Android控件架构概述 在Android应用程序开发过程中,用户界面的构建主要依赖于各种控件(Views),这些控件构成了应用的基本元素。从架构角度来看,Android中的每一...

    Android View.onMeasure方法详解及实例

    Android View.onMeasure 方法详解及实例 Android View.onMeasure 方法是 View 类中非常重要的一个方法,它主要用于测量 View 的尺寸。在安卓系统中,View 在屏幕上显示之前需要经过测量(measure)和布局(layout)...

    详解Android PopupWindow怎么合理控制弹出位置(showAtLocation)

    今天,我们将详细介绍如何合理控制PopupWindow的弹出位置,特别是使用showAtLocation方法。 首先,需要了解PopupWindow的基本使用方法。创建一个PopupWindow需要指定一个ContentView,这个ContentView将会被展示在...

    view类详解

    - 1.1.3 View 类方法及接口详细介绍 - 1.1.4 Android 中 View 类相关常用控件举例 - 1.2 View 类的层次结构关系 2. Android 的屏幕元素体系 ViewGroup - 2.1 Android GUI 程序的屏幕的体系结构 - 2.1.1 体系...

    Android开发之机顶盒上gridview和ScrollView的使用详解

    int expandSpec = MeasureSpec.makeMeasureSpec(Integer.MAX_VALUE >> 2, MeasureSpec.AT_MOST); super.onMeasure(widthMeasureSpec, expandSpec); } } ``` 这种解决方案使得`GridView`的子控件能够获取焦点,...

    Android屏幕及view的截图实例详解

    要获取整个屏幕的截图,可以使用Activity的`getWindow()`方法获取到`Window`对象,然后调用`getDecorView()`来获取装饰视图(包含状态栏、导航栏等)。以下是一个简单的示例: ```java View decorView = ...

    Android-Android开发之自定义View的功能实现详解。教你一步一步学会自定义View

    2. 测量优化:合理设置MeasureSpec,避免过度测量。 3. 使用硬件加速:开启硬件加速可提高View的绘制速度,但需注意兼容性问题。 六、自定义ViewGroup 1. 处理子View的测量与布局,实现复杂的布局结构。 2. 考虑子...

    android如何获取view在布局中的高度与宽度详解

    Android 获取 View 在布局中的高度与宽度详解 在 Android 开发中,获取 View 的宽度和高度是非常常见的需求。然而,很多开发者可能不知道如何正确地获取 View 的宽度和高度。今天,我们将详细介绍四种获取 View 在...

    Android自定义进度条的圆角横向进度条实例详解

    根据MeasureSpec的模式(EXACTLY, AT_MOST, UNSPECIFIED)和尺寸,你可以计算并设置控件的实际大小。 2. **实现圆角进度条的原理** - 圆角进度条通常通过绘制多个矩形实现,底层作为背景,中间层作为进度条的基础...

    Android下拉刷新框架的例子

    你需要根据MeasureSpec(尺寸规格)来计算尺寸,MeasureSpec包含模式(MeasureSpec.MODE)和大小(MeasureSpec.SIZE),理解这两个参数是精确测量的关键。 3. 手势事件处理: Android提供了GestureDetector类来...

Global site tag (gtag.js) - Google Analytics