一个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)
8421 public static int resolveSize(int size, int measureSpec) { 8422 int result = size; 8423 int specMode = MeasureSpec.getMode(measureSpec); 8424 int specSize = MeasureSpec.getSize(measureSpec); 8425 switch (specMode) { 8426 case MeasureSpec.UNSPECIFIED: 8427 result = size; 8428 break; 8429 case MeasureSpec.AT_MOST: 8430 result = Math.min(size, specSize); 8431 break; 8432 case MeasureSpec.EXACTLY: 8433 result = specSize; 8434 break; 8435 } 8436 return result; 8437 }
上面既然要用到measureSpec值,那自然表示这个函数通常是在onMeasure方法里面调用的。简单说一下,这个方法的主要作用就是根据你提供的大小和模式,返回你想要的大小值,这个里面根据传入模式的不同来做相应的处理。
再看看MeasureSpec.makeMeasureSpec方法,实际上这个方法很简单:
9023 public static int makeMeasureSpec(int size, int mode) { 9024 return size + mode; 9025 }
这样大家不难理解size跟measureSpec区别了。看看它的使用吧,ListView.measureItem(View child)
2464 private void measureItem(View child) { 2465 ViewGroup.LayoutParams p = child.getLayoutParams(); 2466 if (p == null) { 2467 p = new ViewGroup.LayoutParams( 2468 ViewGroup.LayoutParams.MATCH_PARENT, 2469 ViewGroup.LayoutParams.WRAP_CONTENT); 2470 } 2471 2472 int childWidthSpec = ViewGroup.getChildMeasureSpec(mWidthMeasureSpec, 2473 mListPadding.left + mListPadding.right, p.width); 2474 int lpHeight = p.height; 2475 int childHeightSpec; 2476 if (lpHeight > 0) { 2477 childHeightSpec = MeasureSpec.makeMeasureSpec(lpHeight, MeasureSpec.EXACTLY); 2478 } else { 2479 childHeightSpec = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED); 2480 } 2481 child.measure(childWidthSpec, childHeightSpec); 2482 }
measureSpec方法通常在ViewGroup中用到,它可以根据模式(MeasureSpec里面的三个)可以调节子元素的大小。
注意,使用EXACTLY和AT_MOST通常是一样的效果,如果你要区别他们,那么你就要使用上面的函数View.resolveSize(int size,int measureSpec)返回一个size值,然后使用你的view调用setMeasuredDimension(int,int)函数。
8406 protected final void setMeasuredDimension(int measuredWidth, int measuredHeight) { 8407 mMeasuredWidth = measuredWidth; 8408 mMeasuredHeight = measuredHeight; 8409 8410 mPrivateFlags |= MEASURED_DIMENSION_SET; 8411 }
然后你调用view.getMeasuredWidth,view.getMeasuredHeigth 返回的就是上面函数里的mMeasuredWidth,mMeasuredHeight的值。
相关推荐
在这个详解例子中,我们将深入探讨MeasureSpec的三种测量模式以及它们如何影响Android UI布局。 1. **UNSPECIFIED模式** UNSPECIFIED模式是最宽松的模式,它表示父视图不对子视图有任何尺寸上的限制。子视图可以...
例如,在LinearLayout中,可以使用MeasureSpec来控制子View的尺寸和布局。 五、MeasureSpec源码解析 Android的MeasureSpec源码位于Android SDK的android.view.View.MeasureSpec.java文件中,该文件定义了...
Android UI绘制流程及原理详解 Android UI绘制流程及原理是 Android 应用程序的核心部分,它负责将用户界面元素绘制到屏幕上。在本篇文章中,我们将详细介绍 Android UI绘制流程及原理,并对相关知识点进行解释。 ...
本文将深入探讨“View坐标位置XY轴详解”,并基于配套博客提供的详细内容进行阐述。 首先,我们要知道Android中的坐标系统是基于左上角为原点(0,0)的二维平面。X轴水平向右延伸,Y轴垂直向下延伸。这是与数学中的...
Log.i("SendView", "widthMode, heightMode: " + MeasureSpec.toString(widthMeasureSpec) + ", " + MeasureSpec.toString(heightMeasureSpec)); setMeasuredDimension(width, height); } ``` 在这个例子中,...
最后,为了提供更好的滚动体验,你还可以考虑实现一些额外的功能,比如滚动动画、滚动边界检测以及与nested滚动的兼容(如果需要在NestedScrollView中嵌套使用)。 在实际项目中,你可以创建一个名为`...
int heightMeasureSpecCustom = MeasureSpec.makeMeasureSpec(Integer.MAX_VALUE >> 2, MeasureSpec.AT_MOST); super.onMeasure(widthMeasureSpec, heightMeasureSpecCustom); setMeasuredDimension...
### Android控件架构和自定义控件详解 #### 一、Android控件架构概述 在Android应用程序开发过程中,用户界面的构建主要依赖于各种控件(Views),这些控件构成了应用的基本元素。从架构角度来看,Android中的每一...
Android View.onMeasure 方法详解及实例 Android View.onMeasure 方法是 View 类中非常重要的一个方法,它主要用于测量 View 的尺寸。在安卓系统中,View 在屏幕上显示之前需要经过测量(measure)和布局(layout)...
今天,我们将详细介绍如何合理控制PopupWindow的弹出位置,特别是使用showAtLocation方法。 首先,需要了解PopupWindow的基本使用方法。创建一个PopupWindow需要指定一个ContentView,这个ContentView将会被展示在...
- 1.1.3 View 类方法及接口详细介绍 - 1.1.4 Android 中 View 类相关常用控件举例 - 1.2 View 类的层次结构关系 2. Android 的屏幕元素体系 ViewGroup - 2.1 Android GUI 程序的屏幕的体系结构 - 2.1.1 体系...
int expandSpec = MeasureSpec.makeMeasureSpec(Integer.MAX_VALUE >> 2, MeasureSpec.AT_MOST); super.onMeasure(widthMeasureSpec, expandSpec); } } ``` 这种解决方案使得`GridView`的子控件能够获取焦点,...
要获取整个屏幕的截图,可以使用Activity的`getWindow()`方法获取到`Window`对象,然后调用`getDecorView()`来获取装饰视图(包含状态栏、导航栏等)。以下是一个简单的示例: ```java View decorView = ...
2. 测量优化:合理设置MeasureSpec,避免过度测量。 3. 使用硬件加速:开启硬件加速可提高View的绘制速度,但需注意兼容性问题。 六、自定义ViewGroup 1. 处理子View的测量与布局,实现复杂的布局结构。 2. 考虑子...
Android 获取 View 在布局中的高度与宽度详解 在 Android 开发中,获取 View 的宽度和高度是非常常见的需求。然而,很多开发者可能不知道如何正确地获取 View 的宽度和高度。今天,我们将详细介绍四种获取 View 在...
根据MeasureSpec的模式(EXACTLY, AT_MOST, UNSPECIFIED)和尺寸,你可以计算并设置控件的实际大小。 2. **实现圆角进度条的原理** - 圆角进度条通常通过绘制多个矩形实现,底层作为背景,中间层作为进度条的基础...
你需要根据MeasureSpec(尺寸规格)来计算尺寸,MeasureSpec包含模式(MeasureSpec.MODE)和大小(MeasureSpec.SIZE),理解这两个参数是精确测量的关键。 3. 手势事件处理: Android提供了GestureDetector类来...