自定义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吧...