Android(安卓)View中的onMeasure()方法详解
onMeasure()方法是哪里的?有什么用?有的人可能会有这种疑问,这里我们就来探讨下此方法
笔者上篇文章中的案例简单接触了onMeasure方法来实现方形View:Android实现正方形View
- 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()方法在什么情况下我们需要用到?怎么用?
在这之前我们需要了解一个疑问:此方法在开发的时候没有调用过啊!那此方法什么时候会被调用?
根据笔者的开发经验来看,以“on”单词开头的方法都是当什么什么时候回调的,也就是说系统在某一时刻会自动调用此方法。知道这点后就行了,就是此方法不要我们关心什么时候调用,它该出手时就出手。
——此方法中的两个参数是什么东西?
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中的现象都不会出现,因为我们只是通过创建一个新的测量空间重新传给父类方法,所有的计算方法我们都没有变,所以此方法是通过的
情景作业
自定义一个TextView,实现宽度是父容器宽度的一半,高度是宽度的一半
PS:希望本文可以帮到大家,有疑问可留言待回复
更多相关文章
- Android中的UI线程详解
- ubuntu 编译 Android(安卓)出现的若干错误及解决方法
- [转]Android(安卓)设计思想
- android sqlite SQLiteDatabase 操作大全 不看后悔!必收藏!看后精
- Android多线程(三)HandlerThread源码原理解析
- android 数据存储之 SharedPreference
- Android单元测试之Robolectric
- XposedHook:hook敏感函数
- Android(安卓)Studio真机测试时生成的程序出现闪退