本文主要记录下对于自定义view中方法的理解。
对于自定义view有三大流程:onMeasure
(测量)、onLayout
(布局)和onDraw
(绘制)
接下来我就要说下onMeasure()
这个方法:
onMeasure
在布局文件中,对于自定义view的layout_width
和layout_height
不设置wrap_content
,一般不需要进行处理,但如果要设置wrap_content
,就要对宽高进行测量。
onMeasure函数原型:
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec)
参数中的widthMeasureSpec
和heightMeasureSpec
里面包含了测量模式和尺寸,在这可以借助Android内置的MeasureSpec类来获取测量模式和尺寸:
int widthMode = MeasureSpec.getMode(widthMeasureSpec);
int widthSize = MeasureSpec.getSize(widthMeasureSpec);
对于测量模式有三种情况:
测量模式 | 含义 |
---|---|
UNSPECIFIED | 父容器没有对当前View有任何限制,当前View可以任意取尺寸 |
EXACTLY | 当前尺寸就是当前View应该取的尺寸,对应于match_parent 和具体数值情况 |
AT_MOST | 当前View所能取的最大尺寸,一般是给定一个大小,view的尺寸不能超过该大小,一般用于wrap_content
|
手重写onMeasure函数
@Overrideprotected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
int width = MeasureSpec.getSize(widthMeasureSpec);
int widthMode = MeasureSpec.getMode(widthMeasureSpec);
int height = MeasureSpec.getSize(heightMeasureSpec);
int heightMode = MeasureSpec.getMode(heightMeasureSpec);
if (widthMode == MeasureSpec.AT_MOST && heightMode == MeasureSpec.AT_MOST) {
setMeasuredDimension(WRAP_WIDTH, WRAP_HEIGHT);
} else if (widthMode == MeasureSpec.AT_MOST) {
setMeasuredDimension(WRAP_WIDTH, height);
} else if (heightMode == MeasureSpec.AT_MOST) {
setMeasuredDimension(width, WRAP_HEIGHT);
}
}
只处理AT_MOST情况也就是wrap_content
,其他情况则沿用系统的测量值即可。setMeasuredDimension
会设置View宽高的测量值,只有setMeasuredDimension
调用之后,才能使用getMeasuredWidth()
和getMeasuredHeight()
来获取视图测量出的宽高,以此之前调用这两个方法得到的值都会是0。
注意:在覆写onMeasure方法的时候,必须调用 setMeasuredDimension(int,int)
来存储这个View经过测量得到的measured width and height。