- onMeasure()方法在哪里?有什么用?
void onMeasure(int widthMeasureSpec, int heightMeasureSpec);
/*
1.此方法在哪里了?
答:如标题所言,在 class View 这个类中,也就是说,我们所有的控件都有这个方法
2.有什么用了?
答:Measure the view and its content to determine the measured width and the measured height.
(测量视图及其内容,以确定所测量的宽度和测量的高度。)
*/
- onMeasure()方法在什么情况下我们需要用到?怎么用?
在这之前我们需要了解一个疑问:此方法在开发的时候没有调用过啊!那此方法什么时候会被调用?
——此方法中的两个参数是什么东西?
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, widthMeasureSpec);
/*获得宽度的测量模式(测量模式见下面介绍class MeasureSpec)*/
final int widthMode = MeasureSpec.getMode(widthMeasureSpec);
/*获得高度的测量模式(测量模式见下面介绍class MeasureSpec)*/
final int heightMode = MeasureSpec.getMode(heightMeasureSpec);
/*获得宽度的尺寸*/
final int widthSize = MeasureSpec.getSize(widthMeasureSpec);
/*获得高度的尺寸*/
final int heightSize = MeasureSpec.getSize(heightMeasureSpec);
}
class MeasureSpec
- MeasureSpec.UNSPECIFIED
笔者经验不足,开发中暂时未发现什么情况下会出现- MeasureSpec.EXACTLY (精确尺寸)
当布局时layout_width、layout_height为fill_parent、macth_parent时为此值,因为子view会占据剩余容器的空间,所以它大小是确定的- MeasureSpec.AT_MOST (最大尺寸)
当布局时layout_width、layout_height为具体的值时为此值,因为我们已经确定了View的宽度或高度,所以它的最大尺寸是我们给的值Public Methods
//*获得参数中的测量空间的测量模式,模式取值上面介绍的三个常量*/ static int getMode(int measureSpec); /*获得参数中的测量空间的尺寸*/ static int getSize(int measureSpec); /*根据传入的参数尺寸size与模式mode制造出一个测量空间值*/ static int makeMeasureSpec(int size, int mode);
情景需求
实现一个View,使它的高度等于宽度的一半,直接上关键代码
思路1:在onMeasure方法中通过MeasureSpec.getSize(int measureSpec)方法获得宽度的尺寸width,然后用获得宽度值width/2算出高度值height,然后调用setMeasuredDimension(measuredWidth,measuredHeight)实现
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { int widthSize = MeasureSpec.getSize(widthMeasureSpec); int heightSize = widthSize/2; setMeasuredDimension(widthSize,heightSize); }
思路2:在onMeasure方法中通过MeasureSpec.getSize(int measureSpec)方法与MeasureSpec.getMode(int measureSpec)方法获得宽度的尺寸width与宽度的模式mode,然后用获得宽度值width/2算出高度值height,然后调用MeasureSpec.makeMeasureSpec(int size, int mode)方法将算出的高度height与取到的模式mode分别传入得到一个测量空间数据heightMeasureSpec,此值其实就是我们需要的高度测量空间值,然后我们调用super.onMeasure(widthMeasureSpec, widthMeasureSpec)实现
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { int widthSize = MeasureSpec.getSize(widthMeasureSpec); int height = widthSize / 2; int heightMode = MeasureSpec.getMode(widthMeasureSpec); heightMeasureSpec = MeasureSpec.makeMeasureSpec(height, heightMode); super.onMeasure(widthMeasureSpec,heightMeasureSpec); }
两种方法有什么不同?<笔者推荐思路2>
思路1:不适用于ViewGrop,当自定义ViewGrop这样实现onMeasure()方法,子View无法显示,读者可尝试;当自定义TextView等这些控件时,比例可能会满足我们的需求,但尺寸可能会超出我们的想象,读者可尝试;
思路2:思路1中的现象都不会出现,因为我们只是通过创建一个新的测量空间重新传给父类方法,所有的计算方法我们都没有变,所以此方法是通过的