在官方文档中对Drawable的定义为:可绘制物件的一般抽象(A Drawable is a general abstraction for 『something that can be drawn』)。『可绘制的』本身也是个抽象的概念,而且容易让我们联想到Android里另一个较抽象的概念『View』,我们知道View也是可以绘制的,那View是不是也可以称为Drawable呢?官方的文档中也有这样一句:Unlike a View, a Drawable does not have any facility to receive events or otherwise interact with the user. Drawable与View不同,Drawable不接受事件,无法与用户进行交互。也就是说与Drawable相比View更轻量级。
我们在开发中也经常对图片设置点击事件,明明可以接受和响应事件啊,但是仔细想想,响应事件的是ImageView,而不是我们显示在ImageView上的Drawable,所以这也正体现了View和Drawable的区别。
与Drawable相关的源码全在
android/platform/frameworks/base/graphics/java/android/graphics/drawable/包下。
Drawable中几个比较常用的创建一个Drawable对象静态方法。
Drawable类继承图
Drawable是一个抽象类,Android FrameWork提供了一些具体的Drawable实现,它们的继承关系如下图:
Drawable的分类
不同的图形图像资源就代表着不同的drawable类型。Android中具体的Drawable实现有:
- Bitmap File 普通的位图文件(.png, .jpg, or .gif) 对应一个BitmapDrawable对象,XML中的根元素为。
- Nine-Patch File 即我们常说的”点九图”,可以基于自动适应内容大小而伸缩区域的png图片,创建一个NinePatchDrawable对象。
- Layer List 用来管理多个drawable的数组,索引值最大的图层绘制在最上面,创建一个LayerDrawable对象,XML中的根元素为。
- State List 用来根据不同的状态来引用不同的位图图形,创建一个StateListDrawable对象,XML中的根元素为。
- Level List 一个LeveListDrawable管理着一组交替的drawable资源,level-list中某项的android:maxLevel数值大于或者等于setLevel设置的数值,就会被加载,创建一个LevelListDrawable对象,XML中的根元素为。。
- Transition Drawable 定义一个可以在两张图片资源之间实现淡入淡出效果的TransitionDrawable对象,XML中的根元素为。
- Inset Drawable 定义一个根据指定的距离嵌入到另一个drawable的图片资源,创建一个TransitionDrawable对象,XML中的根元素为。
- Clip Drawable 定义一个从当前drawable上截取一个”图片片段”的图片类型,创建一个ClipDrawable对象,XML中的根元素为。
- Scale Drawable 定义一个基于当前的level,对当前drawable进行尺寸缩放后的drawable类型,XML中的根元素为。
- Shape Drawable 定义一个包含颜色和渐变的几何图形,创建一个 ShapeDrawable对象,XML中的根元素为。
- Animation Drawable 表示逐帧动画,xml中的根元素为
- Color Drawable 颜色资源也可以作为一个drawable.例如我们在设置一个View的background时,经常使用android:drawable=”@color/blue”的方式。
详细的信息可以查看官方文档:
http://developer.android.com/intl/zh-cn/guide/topics/resources/drawable-resource.html
除了这些预置的drawable实现类以外,也可以自定义drawable的实现类型,但是Android FrameWork提供的drawable实现类型已经能满足绝大部分的需求。在实际开发中,我们一般通过xml文件来定义复杂的drawable类型,只有在程序中需要修改drawable的属性时,才需要使用具体的drawable类型提供的方法来处理。
在上面的分类中,Bitmap,Nine-Patch,State List比较常用。例如一个按钮的不同状态下的背景图片就是通过State List实现,
<?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>
Level List使用较少,但也比较简单,比如WiFi信号会根据不同的强度显示不同的图片。
<level-list xmlns:android="http://schemas.android.com/apk/res/android">
<item android:maxLevel="0" android:drawable="@drawable/ic_wifi_signal_1" />
<item android:maxLevel="1" android:drawable="@drawable/ic_wifi_signal_2" />
<item android:maxLevel="2" android:drawable="@drawable/ic_wifi_signal_3" />
<item android:maxLevel="3" android:drawable="@drawable/ic_wifi_signal_4" />
</level-list>
另外的几种类型将单独介绍。
原文链接:https://liuzhichao.com/2016/android-drawable.html
其他几篇:
Android Drawable之LayerDrawable
Android Drawable之TransitionDrawable
Android Drawable之InsetDrawable