Drawable绘图

Drawable表示一种可以在Canvas上进行绘制的抽象概念,它的种类有很多,比如颜色和图片都可以是一个Drawable,可以使用Drawable方便地定义一些特殊的UI效果。使用Drawable定义UI效果有几个优势:首先,使用方式比自定义View简单得多;其次,非图片类型的Drawable占用空间较少,可以减少APK的体积。

Drawable介绍

在实际开发中,Drawable通常被用来作为View的背景。一般通过XML来定义Drawable,也可以使用代码创建Drawable对象,不过流程会相对复杂。在Android中,Drawable是一个抽象类,所有Drawable对象都是它的子类,比如ShapeDrawable、BitmapDrawable等。

Drawable的内部宽/高是比较重要的参数,可以通过getIntrinsicWidth()和getIntrinsicHeight()方法获取。注意,不是所有的Drawable都有内部宽/高,比如,一张图片所形成的Drawable,它的内部宽/高就是图片的宽/高,但是,一个颜色形成的Drawable,就没有内部宽/高的概念。另外,Drawable的内部宽/高不等于它的大小,一般来说,Drawable没有大小的概念,当用作View的背景时,Drawable会被拉伸或缩小至和View等同的大小。

Drawable的类别

Drawable的种类有很多,下面介绍一些常用的Drawable。

BitmapDrawable

在XML中使用Bitmap的语法如下所示:

1
2
3
4
5
6
7
8
9
10
11
12
<?xml version="1.0" encoding="utf-8"?>
<bitmap
xmlns:android="http://schemas.android.com/apk/res/android"
android:src="@[package:]drawable/drawable_resource"
android:antialias=["true" | "false"]
android:dither=["true" | "false"]
android:filter=["true" | "false"]
android:gravity=["top" | "bottom" | "left" | "right" | "center_vertical" |
"fill_vertical" | "center_horizontal" | "fill_horizontal" |
"center" | "fill" | "clip_vertical" | "clip_horizontal"]
android:mipMap=["true" | "false"]
android:tileMode=["disabled" | "clamp" | "repeat" | "mirror"] />

通过这种方式引用图片,可以直接将res中只读的图片资源转成Bitmap对象使用。

ShapeDrawable

在XML中使用Shape的语法如下所示:

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
<?xml version="1.0" encoding="utf-8"?>
<shape
xmlns:android="http://schemas.android.com/apk/res/android"
android:shape=["rectangle" | "oval" | "line" | "ring"] >
<corners
android:radius="integer"
android:topLeftRadius="integer"
android:topRightRadius="integer"
android:bottomLeftRadius="integer"
android:bottomRightRadius="integer" />
<gradient
android:angle="integer"
android:centerX="float"
android:centerY="float"
android:centerColor="integer"
android:endColor="color"
android:gradientRadius="integer"
android:startColor="color"
android:type=["linear" | "radial" | "sweep"]
android:useLevel=["true" | "false"] />
<padding
android:left="integer"
android:top="integer"
android:right="integer"
android:bottom="integer" />
<size
android:width="integer"
android:height="integer" />
<solid
android:color="color" />
<stroke
android:width="integer"
android:color="color"
android:dashWidth="integer"
android:dashGap="integer" />
</shape>

Shape是XML绘图的关键,无论是扁平化、拟物化还是渐变,它都可以实现。

LayerDrawable

在XML中使用Layer的语法如下所示:

1
2
3
4
5
6
7
8
9
10
11
<?xml version="1.0" encoding="utf-8"?>
<layer-list
xmlns:android="http://schemas.android.com/apk/res/android" >
<item
android:drawable="@[package:]drawable/drawable_resource"
android:id="@[+][package:]id/resource_name"
android:top="dimension"
android:right="dimension"
android:bottom="dimension"
android:left="dimension" />
</layer-list>

通过Layer可以很方便地实现图层叠加的效果。

StateListDrawable

StateList用于定义可绘制对象,它根据对象的状态,使用多个不同的图像来表示同一个图形。

在XML中使用StateList的语法如下所示:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android"
android:constantSize=["true" | "false"]
android:dither=["true" | "false"]
android:variablePadding=["true" | "false"] >
<item
android:drawable="@[package:]drawable/drawable_resource"
android:state_pressed=["true" | "false"]
android:state_focused=["true" | "false"]
android:state_hovered=["true" | "false"]
android:state_selected=["true" | "false"]
android:state_checkable=["true" | "false"]
android:state_checked=["true" | "false"]
android:state_enabled=["true" | "false"]
android:state_activated=["true" | "false"]
android:state_window_focused=["true" | "false"] />
</selector>

通过StateList可以快速实现View的触摸反馈。通过配置不同的触发事件,自动选择不同的图像作为背景图。

更多

以上只是介绍了常用的Drawable,更多Drawable的使用可以参考官方文档

另外,Drawable是可以相互配合使用的,比如在selector中的Item中使用shape实现圆角的背景图片。

坚持原创技术分享,您的支持将鼓励我继续创作!