onMeasure方法在控件的父元素正要放置它的子控件时调用。它会问一个问题,“你想要用多大地方啊?”,然后传入两个参数——widthMeasureSpec和heightMeasureSpec。它们指明控件可获得的空间以及关于这个空间描述的元数据。比返回一个结果要好的方法是你传递View的高度和宽度到setMeasuredDimension方法里。
接下来的代码片段给出了如何重写onMeasure。注意,调用的本地空方法是来计算高度和宽度的。它们会译解widthHeightSpec和heightMeasureSpec值,并计算出合适的高度和宽度值。
Java代码:
@Override
protectedvoidonMeasure(intwidthMeasureSpec,intheightMeasureSpec){
intmeasuredHeight=measureHeight(heightMeasureSpec);
intmeasuredWidth=measureWidth(widthMeasureSpec);
setMeasuredDimension(measuredHeight,measuredWidth);
}
privateintmeasureHeight(intmeasureSpec){
//高度测量窗口的回归.
}
privateintmeasureWidth(intmeasureSpec){
//还测量窗口的宽度.
}
边界参数——widthMeasureSpec和heightMeasureSpec,效率的原因以整数的方式传入。在它们使用之前,首先要做的是使用MeasureSpec类的静态方法getMode和getSize来译解,如下面的片段代码所示:
Java代码:
intspecMode=MeasureSpec.getMode(measureSpec);
intspecSize=MeasureSpec.getSize(measureSpec);
接下来的框架代码给出了处理View测量的典型实现:
Java代码:
@Override
protectedvoidonMeasure(intwidthMeasureSpec,intheightMeasureSpec){
intmeasuredHeight=measureHeight(heightMeasureSpec);
intmeasuredWidth=measureWidth(widthMeasureSpec);
setMeasuredDimension(measuredHeight,measuredWidth);
}
privateintmeasureHeight(intmeasureSpec){
intspecMode=MeasureSpec.getMode(measureSpec);
intspecSize=MeasureSpec.getSize(measureSpec);
//如果没有限制默认大小是指定的.
intresult=500;
if(specMode==MeasureSpec.AT_MOST)
{
//你理想的大小的计算
//在这个最大值控制.
//如果你能控制的充满可用
//外太空返回束缚.
result=specSize;
}
elseif(specMode==MeasureSpec.EXACTLY)
{
//如果你的控制能符合这些界限返回那个价值.
result=specSize;
}
returnresult;
}
privateintmeasureWidth(intmeasureSpec){
intspecMode=MeasureSpec.getMode(measureSpec);
intspecSize=MeasureSpec.getSize(measureSpec);
//如果没有限制默认大小是指定的.
intresult=500;
if(specMode==MeasureSpec.AT_MOST)
{
//理想尺寸的计算你的控制
//在这个最大的尺寸。
//如果你的控制填充的可用空间
//返回外面的束缚。
result=specSize;
}
elseif(specMode==MeasureSpec.EXACTLY)
{
//如果你的控制能符合这些界限返回那个价值.
result=specSize;
}
returnresult;
}
的要求。一个MeasureSpec包含一个尺寸和模式。
有三种可能的模式:
UNSPECIFIED:父布局没有给子布局任何限制,子布局可以任意大小。
EXACTLY:父布局决定子布局的确切大小。不论子布局多大,它都必须限制在这个界限里。
AT_MOST:子布局可以根据自己的大小选择任意大小。
为了减少内存分配,MeasueSpecs用整数表示。这个类提供打包和解包<size,mode>元组为整型。参考方法:public static int makeMeasureSpec(int size,int mode)。
分享到:
相关推荐
MeasureSpec是Android系统中用于布局管理的一个重要概念,它在处理View的尺寸计算时起到关键作用。MeasureSpec是由两个部分组成的:mode(模式)和size(大小)。在这个详解例子中,我们将深入探讨MeasureSpec的三种...
1. 当子View的LayoutParams的宽(高)采用具体的值(如100px)时且父容器的MeasureSpec为MeasureSpec.EXACTLY或者MeasureSpec.AT_MOST或者MeasureSpec.UNSPECIFIED时:系统返回给该子View的specMode就为MeasureSpec....
int expandSpec = MeasureSpec.makeMeasureSpec(Integer.MAX_VALUE >> 2,MeasureSpec.AT_MOST); super.onMeasure(widthMeasureSpec, expandSpec); } 搜索功能其实没写进demo里面,从项目里整理出来太麻烦了。...
mode共有三种情况,取值分别为MeasureSpec.UNSPECIFIED, MeasureSpec.EXACTLY, MeasureSpec.AT_MOST。 MeasureSpec.EXACTLY是精确尺寸, 当我们将控件的layout_width或layout_height指定为具体数值时如andorid ...
1. **设置MeasureSpec**:MeasureSpec是一个组合了模式(MeasureSpec MODE)和大小(MeasureSpec SIZE)的32位整数。它包含了父视图对当前视图的尺寸限制。MeasureSpec有三种模式: - `MeasureSpec.EXACTLY`:父...
`onMeasure`方法用于计算控件的大小,它有三种测量模式:MeasureSpec.EXACTLY、MeasureSpec.AT_MOST和MeasureSpec.UNSPECIFIED。 1. **MeasureSpec.EXACTLY**:这是最常见的模式,表示父视图已经指定了确切的大小。...
int specMode = MeasureSpec.getMode(measureSpec); int specSize = MeasureSpec.getSize(measureSpec); if (specMode == MeasureSpec.EXACTLY) { result = specSize; } else { // 设置默认宽度 result = ...
MeasureSpec包含模式(MeasureSpec MODE)和大小(Size)两部分,模式分为EXACTLY(固定大小)、AT_MOST(最大不超过)和UNSPECIFIED(无限制)。我们需要根据MeasureSpec来计算视图的实际大小。 例如,如果要动态...
`onMeasure()`方法有两个参数:`MeasureSpec`,它们分别代表父容器对View宽度和高度的要求。MeasureSpec包含两个部分:模式(Mode)和大小(Size)。模式可以是EXACTLY(表示必须精确到给定大小)、AT_MOST(表示不...
此方法接收两个参数,`MeasureSpec`对象,分别代表父视图对当前视图宽度和高度的要求。MeasureSpec包含一个模式(MODE)和一个大小(SIZE)。模式有三种:EXACTLY(精确)、AT_MOST(最大不超过)和UNSPECIFIED(未...
int childHeightMeasureSpec = MeasureSpec.makeMeasureSpec(parentHeight, MeasureSpec.AT_MOST); for (int i = 0; i (); i++) { getChildAt(i).measure(childWidthMeasureSpec, childHeightMeasureSpec); } ...
通过`MeasureSpec`的`makeMeasureSpec`方法可以创建一个MeasureSpec,同时可以用`getMode`和`getSize`获取其specMode和specSize。 在View的`onMeasure`方法中,通常会调用`setMeasuredDimension`来设置View的测量...
int specMode = MeasureSpec.getMode(measureSpec); int specSize = MeasureSpec.getSize(measureSpec); switch (specMode) { case MeasureSpec.EXACTLY: // 父视图指定了确切的大小,使用这个大小 result = ...
heightMeasureSpec = MeasureSpec.makeMeasureSpec(heightSize + statusBarHeight, MeasureSpec.EXACTLY); } } super.onMeasure(widthMeasureSpec, heightMeasureSpec); if (heightMode != MeasureSpec....
在自定义View或ViewGroup时,需要根据父容器的MeasureSpec和自己的LayoutParams来计算自己的MeasureSpec。 结论 ---- 自定义View和ViewGroup是Android应用程序中非常重要的组件,它们都是Android UI组件树的基础。...
`onMeasure()`方法接收两个参数:`MeasureSpec`对象,分别代表父视图对当前视图宽度和高度的要求。 MeasureSpec包含两个部分:模式(Mode)和大小(Size)。模式分为三种: 1. `EXACTLY`:父视图已经确定了具体的...
webView.measure(MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED), MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED)); webView.layout(0, 0, webView.getMeasuredWidth(), webView....
setMeasuredDimension(measureSpec(widthMeasureSpec), measureSpec(heightMeasureSpec)); } private int measureSpec(int measureSpec) { int result = 0; int specMode = MeasureSpec.getMode(measureSpec); ...
模式有三种:MeasureSpec.EXACTLY表示精确大小,MeasureSpec.AT_MOST表示最大允许大小,MeasureSpec.UNSPECIFIED表示没有限制。尺寸则是父View建议的大小。 在`onMeasure()`方法中,View会根据这些规格计算自己的...