Android Drawable

Drawable 简介

Drawable 表示一种可以在 Canvas 上进行绘制的抽象的概念,种类很多,常见的比如颜色或图片。

Drawable 的分类

BitmapDrawable

表示的一张图片,可以直接引用原始的图片或通过 XML 的方式来描述它。
NinePatchDrawable 表示一张 .9 格式的图片,使用也是一样的。
BitmapDrawable 也可以代表一个 .9 格式图片。

ShapeDrawable

可理解为通过颜色来构造的图形,可以是纯色的图形,也可以是具有渐变效果的图形。
<shape>标签创建的 Drawable,其实体类是 GradientDrawable。

LayerDrawable

其对应的 XML 标签是<layer-list>,表示一种层次化的 Drawable 集合。

StateListDrawable

对应于<selector>标签,也是表示 Drawable 集合,每个 Drawable 对应着 View 的一种状态。

LevelListDrawable

对应于<level-list>标签,同样表示一个 Drawable 集合,每个 Drawable 都有一个等级(level)的概念。

TransitionDrawable

对应于<transition>标签,用于两个 Drawable 之间的淡入淡出效果。

InsetDrawable

对应<inset>标签,可将其它 Drawable 内嵌到自己当中,并可以在四周留出一定的间距。
当 View 希望背景比自己的实际区域小时,可采用。

ScaleDrawable

对应<scale>标签,可根据自己等级(level)将指定的 Drawable 缩放到一定比例。

ClipDrawable

对应<clip>标签,可根据自己当前等级(level)来裁剪另一个 Drawable。


自定义 Drawable

Drawable 的工作原理其核心就是 draw()。可通过重写 Drawable 的 draw() 来自定义 Drawable。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
/**
* 可作为 View 的通用背景
*/

public class CustomDrawable extends Drawable{

private Paint mPaint;

public CustomDrawable(int color) {
mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
mPaint.setColor(color);
}

@Override
public void draw(@NonNull Canvas canvas) {
final Rect r = getBounds();
float cx = r.exactCenterX();
float cy = r.exactCenterY();
canvas.drawCircle(cx,cy,Math.min(cx,cy),mPaint);
}

@Override
public void setAlpha(int alpha) {
mPaint.setAlpha(alpha);
invalidateSelf();
}

@Override
public void setColorFilter(@Nullable ColorFilter colorFilter) {
mPaint.setColorFilter(colorFilter);
invalidateSelf();
}

@Override
public int getOpacity() {
// not sure,so be safe
return PixelFormat.TRANSLUCENT;
}

/**
* 当自定义的 Drawable 有固定大小时最好重写这两个方法,
* 因为它会影响到 View 的 wrap_content 布局。
*
* 不重写时,内部宽高为 -1,
* 内部大小不等于实际区域大小,
* 实际大小可通过 getBounds() 得到。
*/
@Override
public int getIntrinsicHeight() {
return super.getIntrinsicHeight();
}

@Override
public int getIntrinsicWidth() {
return super.getIntrinsicWidth();
}
}

链接

参考资料:
Android 开发艺术探索