Drawable介绍与自定义
介绍
Drawable是一种能画在Canvas的抽象,它的一个核心方法drawable.draw(Canvas)将自身的内容画在Canvas上。与Drawable密切联系的是View与Canvas,他们的关系如下
| 元素 | 比喻 | 
|---|---|
| View | 艺术家 | 
| Canvas | 画板 | 
| Drawable | 艺术家脑子的的图案 | 
整个画画的过程就是 ,艺术家(View)将抽象的图案(Drawable)具体画到 画板(Canvas),这强调View同时操作了Canvas与Drawable
Drawable的绘制
静态绘制
静态绘制也就是说Drawable是静态的图案
- Drawable会先向View建议大小宽高,但是最终宽高还是由View说的算
- View通过drawable.setBounds()设置Drawable的最终宽高
- View再调用drawable.draw() 在Canvas画上Drawable
动态绘制
动态绘制也就是说Drawable会画动态图案,动态绘制的Drawable一般会继承DrawableContainer,并且实现Runnable, Animatable,但是在实践中,继承DrawableContainer容易产生OOM的问题,这是因为在DrawableContainer里面每个元素都是强引用,元素太多就OOM啦。如AnimationDrawable:public class AnimationDrawable extends DrawableContainer implements Runnable, Animatable
动态绘制相关类
- Animatable: - 1 
 2
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16- public interface Animatable { 
 /**
 * 开始动画
 */
 void start();
 /**
 * 结束动画
 */
 void stop();
 /**
 *动画是否在运行
 */
 boolean isRunning();
 }
- CallBack - 1 
 2
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16- public static interface Callback { 
 /**
 * 简单来说,重新调View的draw方法
 */
 public void invalidateDrawable(Drawable who);
 /**
 * 在某一时刻实践执行 Runnable,如果说是延迟一段实践执行,则使用SystemClock.uptimeMillis()+延迟的时间 来代替when
 */
 public void scheduleDrawable(Drawable who, Runnable what, long when);
 /**
 * 取消上一次的scheduleDrawable
 */
 public void unscheduleDrawable(Drawable who, Runnable what);
 }
这里其实本来应该Drawable与View(ImageView)互调,但是加了个Callback解除了双向依赖,比如Listener也是这种原理。
- Drawable中三个对应方法
 Drawable中有invadiateSelf,sheduleSelf,unscheduleSelf三个方法分别对应Callback中三个接口,这样不用判断Callback是否为空,直接在Drawable中调用这三个实现好的方法即可。
综上,实现动态的Drawable:
- Callback方面,View,ImageView已经为我们实现了,但由于Drawable需要向Callback.scheduleDrawable传入下一帧Runnable的回调,所以Callback通常也实现Runnable接口
- Drawable必须实现Animtable
Drawable其他机制:
添加State状态支持
- 重写isStateful方法,返回true
- setState中可以使用

