自定义View之onMeasure()(一)
在自定义View中,常常碰见onMeasure(),onLayout(),onDraw()三个方法,还有onTouchEvent(),可以构建我们想要实现的控件。
我们知道,无论是我们自定义的View还是系统自带的View(例如button,textview),都是放在ViewGroup容器中,也就是所说的该控件的父容器(比如LinearLayout、RelativeLayout)中,那么这三个方法了就决定了以下事情:onMeasure()——测量自定义View的大小;onLayout()——放置在ViewGroup容器的具体哪个位置;onDraw()——如何绘制这个View(可以画扇形、圆、矩形、线条等等,只要你能想到就能画出来)。
1、onMeasure():
先看看这个方法的参数
1
2@Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20@Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { super.onMeasure(widthMeasureSpec, heightMeasureSpec); int wSize=MeasureSpec.getSize(widthMeasureSpec); int wMode=MeasureSpec.getMode(widthMeasureSpec); int hSize=MeasureSpec.getSize(heightMeasureSpec); int hMode=MeasureSpec.getMode(heightMeasureSpec); if(wMode==MeasureSpec.EXACTLY){ mWidth=wSize; }else { mWidth=DensityUtil.dip2px(context, 300); } if(hMode==MeasureSpec.EXACTLY){ mHeight=hSize; }else { mHeight=DensityUtil.dip2px(context, 400); } System.out.println("mWidth....."+mWidth+"mHeight>>>>>"+mHeight); setMeasuredDimension(mWidth, mHeight); }
通过查阅onMeasure()Android源码,所有View的onMeasure()的最后一行都调用了setMeasureDimension(宽值,高值),它的作用就是告诉父容器,我的大小是多少,而以前所有的工作都是为这句代码做准备工作的。
而ViewGroup给View分配空间的条件是由specMode决定的,specMode一共有三种可能:
一、 MeasureSpec.EXACTLY:父视图希望子视图的大小应该是specSize中指定的。什么意思了?就是说子视图的大小就是specSize指定的,上面例子中测出宽高的specSize值为多大,子视图宽高就是多大;
二、 MeasureSpec.AT_MOST:子视图的大小最多是specSize中指定的值,也就是说不建议子视图的大小超过specSize中给定的值;
三、MeasureSpec.UNSPECIFIED:我们可以随意指定视图的大小,这个用处很少,不了解也罢。
经过测试,得出,在布局中,View属性设定中,Android:layout_widht="match_parent",或者Android:layout_widht="60dip",那么对应于EXACTLY,也就是子视图告诉父容器,大小是确定的;Android:layout_widht="wrap_content"对应于AT_MOST。
通过以上这些分析,可以知道视图最终的大小由父视图,子视图以及程序员根据需要决定,良好的设计一般会根据子视图的measureSpec设置合适的布局大小。
现在回过头来看看上面那段项目中的代码,那段代码的初衷就是如果开发者设定了自定义View的确定大小(测量出来的specMode为EXACTLY),那么按照开发者设定的测量宽高;如果开发者没有确定大小(测量出来的specMode为AT_MOST),那么宽设定为300dip,高设定为400dip,当然要转为像素,做了转化处理,最后大家看,一定调用了setMeasureDimesion(参数1,参数2),把测量的结果传进去,所以大家就不难理解上面蓝色标注的那段话了,再重复一遍——所有View的onMeasure()的最后一行都调用了setMeasureDimension(宽值,高值),它的作用就是告诉父容器,我的大小是多少,而以前所有的工作都是为这句代码做准备工作的。
今天就写到这儿,如果大家还不理解,可以留言,只要留言肯定解决。
最后
以上就是刻苦冰棍最近收集整理的关于安卓开发中自定义View之onMeasure(),onLayout(),onDraw()讲解(一)的全部内容,更多相关安卓开发中自定义View之onMeasure()内容请搜索靠谱客的其他文章。
发表评论 取消回复