自定义View (二)---onMeasure
上一篇已经写成功做出一个自定义View ,对基本的方法已经学习了,但是那个View只是一个固定大小的,无法像adnroid其他控件一样,在布局文件中修改大小。那么现在我们得学习一下自定义View设置大小的onMeasure方法!
本来昨天想写的,但是发觉有点没学习状态,后天新功能又要开始做了,再不写怕之后拖拉症又犯,所以今天赶紧整理了下思路,先来学习下onMeasure类的使用。其实这网上百度也有一大堆了,很多也是借鉴的别人的解说,我就归纳一下写一遍加深下自己的印象,印证下自己的理解!
onMeasure
想如系统控件一样控制自己View 的大小,首先直接在类中重写onMeasure,进入源码解释可以得到说明,
* Measure the view and its content to determine the measured width and the
* measured height. This method is invoked by {@link #measure(int, int)} and
* should be overridden by subclasses to provide accurate and efficient
* measurement of their contents.
这是一个测量用的类,也就是绘制宽高设置内容大小的意思吧,
onMeasure:有两个参数,widthMeasureSpec,heightMeasureSpec,表示控件可获得的空间和关于这个空间的元数据。通常由父视图计算后传给子视图,从而有一定的控制子视图的大小。
而用到测量,再翻看学习别人的博客时了解到另一个类:
MeasureSpec类:
它是Android系统提供了一个设计了一个短小精悍却功能强大的类--MeasureSpec类,通过它们来帮助我们测量View。
MeasureSpec是一个32位的int值,其中高2位为测量模式,低30位为测量的大小。
主要来说说这个类吧,本来写的很顺的,但是到这里卡壳了....因为网上资料虽然很多,但是各有各的理解吧...
先上一张整体图,拿宽的获取来解说:
MeasureSpec 类里面有三种测量模式,我理解为:
自适应, AT_MOST , layout_with = wrap_content
固定大小, ---> EXACTLY 200dp,math_parent
任意大小 UNSPECIFIED 这种比较少见
不知道怎么说大家能不能理解。
官方的解释为:
/** * Measure specification mode: The parent has not imposed any constraint * on the child. It can be whatever size it wants. */ public static final int UNSPECIFIED = 0 << MODE_SHIFT; /** * Measure specification mode: The parent has determined an exact size * for the child. The child is going to be given those bounds regardless * of how big it wants to be. */ public static final int EXACTLY = 1 << MODE_SHIFT; /** * Measure specification mode: The child can be as large as it wants up * to the specified size. */ public static final int AT_MOST = 2 << MODE_SHIFT;
AT_MOST: 子控件可以像想要的大小,就是说当自适应时,只要是父控件大小范围内随意设置。在用wrap时会走这个模式;
EXACTLY: 父控件给予了一个固定的大小,子控件只能在这个范围内。也就是固定写了多少dp的大小时会调用此处模式;
UNSPECIFIED : 父控件不做任何限制,子控件可以是任意大小。表示大小任意,但是这种比较少见,没怎么遇到,主要还是上面 两种。
然后,我们首先通过getMode,获取宽高的设置模式,getSize,获取设置的大小,return 一个int值回去做显示。
下面放上一张图做详细解释:
首先说红色箭头,这里是将高度设置了300dp的固定值,那么绘制时走的是EXACTLY模式,获取到父控件的高度,因为手机像素尺寸的转换300==900,所以直接是固定了高度的显示。
然后说蓝色箭头,蓝色指向的是宽度,而宽度我们写的是wrap_content,那么首先走向的是AT_MOST模式,这里之前写的是文字大小,所以是TxSzie请不要介意,此处就是说现在调用的是txSize这个数值,然后因为这个AT_MOST模式里面父控件为1080,所以设置的200dp没有问题,那么就成功绘制好了的。
也就是下面这个简单的图片了。
蓝底就是我们这个控件的大小了的,我只是无聊又往里面画了个圆玩耍的...
额,这篇就这样,写的不是很好,但应该看的懂了的...
下篇在继续学习canvas吧...