Drawable 简介
Drawable 有很多种,它们都表示一种图像的概念,但它们又不全是图片,通过颜色也可以构造出各种各样的图像效果。在实际开发中,Drawable 常被用来作为 View 的背景使用。Drawable 一般都是通过 XML 来定义的,当然也可以通过代码来创建具体的 Drawable 对象,只是用代码创建会稍显复杂复杂。在 Android 的设计中,Drawable 是一个抽象类,它是所有 Drawable 对象的基类,每个具体的 Drawable 都是它的子类,比如 ShapeDrawable、BitmapDrawable 等。
Drawable 的内部宽/高这个参数比较重要,通过 getIntrinsicWidth 和 getIntrinsicHeight 这两个方法可以获取到它们。但并不是所有的 Drawable 都有内部宽/高,比如一张图片所形成的 Drawable,它的内部宽/高就是图片的宽/高,但是一个颜色所形成的 Drawable,它就没有内部宽/高的概念。另外要注意的是 Drawable 的内部宽/高并不等同于它的大小,一般来说,Drawable 是没有大小概念的,当用作 View 的背景时,Drawable 会被拉伸至 View 的同等大小。
与 bitmap 的区别
Bitmap 是位图信息的存储,即⼀个矩形图像每个像素的颜⾊信息的存储器。
Drawable 是⼀个可以调⽤ Canvas 来进⾏绘制的上层⼯具。调⽤ Drawable.draw(Canvas) 可以把 Drawable 设置的绘制内容绘制到 Canvas 中。
drawable 简单使用如下代码:
1 | public class DrawableView extends View { |
绘制的一般代码类似“ canvas.drawXXX ”,而 drawable 使用“ drawable.draw(canvas) ”,为什么不是类似“ canvas.drawDrawable(drawable) ”这样的代码?事实上 drawable 是一个小型的更专注的 view ,它只负责绘制。drawable 并不是一个被绘制的对象,像 bitmap、line、circle、path 之类,它们都是“被” canvas 绘制的对象;drawable 更像 view ,它是去“拿” canvas 绘制。drawable 持有 canvas ,并按照自己的规则来绘制。
Drawable 内部存储的是绘制规则,这个规则可以是⼀个具体的 Bitmap,也可以是⼀个纯粹的颜⾊,甚⾄可以是⼀个抽象的、灵活的描述。 Drawable 可以不含有具体的像素信息,只要它含有的信息⾜以在 draw(Canvas) ⽅法被调⽤时进⾏绘制就够了。
由于 Drawable 存储的只是绘制规则,因此在它的 draw() ⽅法被调⽤前,需要先调⽤ Drawable.setBounds() 来为它设置绘制边界。
Bitmap 和 Drawable 的互相转换
事实上,由于 Bitmap 和 Drawable 是两个不同的概念( Bitmap 是像素信息, Drawable 是一个抽象的、功能单一只负责绘制的 View ),因此确切地说它们并不是互相“转换”——一个完整的图像像素信息无法转换成一个所谓的绘制规则,⽽是从其中⼀个获得另⼀个的对象。
- Bitmap -> Drawable:创建⼀个 BitmapDrawable。将 Bitmap 包在一个 Drawable 内, Drawable 的规则就是将 Bitmap 原封原样绘制出来。类似如下代码:
1 | Drawable drawbale = new BitmapDrawable(getResources(),bitmap); |
- Drawable -> Bitmap:如果是 BitmapDrawable,使⽤ BitmapDrawable.getBitmap() 直接获取;如果不是,创建⼀个 Bitmap 和⼀个 Canvas,使⽤ Drawable 通过 Canvas 把内容绘制到 Bitmap 中。代码见 BitmapUtils 中的 drawableToBitmap 方法。
参考资料:
《Android 开发艺术探索》任玉刚 第6章 6.1 Drawable 简介
腾讯课堂 HenCoder