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
16public interface Animatable {
/**
* 开始动画
*/
void start();
/**
* 结束动画
*/
void stop();
/**
*动画是否在运行
*/
boolean isRunning();
}CallBack
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16public 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中可以使用