Overview

官方文档中对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 public Methods
Drawable public Methods

Drawable类继承图

Drawable是一个抽象类,Android FrameWork提供了一些具体的Drawable实现,它们的继承关系如下图:

Android Drawable
Android Drawable

Drawable的分类

不同的图形图像资源就代表着不同的drawable类型。Android中具体的Drawable实现有: * Bitmap File 普通的位图文件(.png, .jpg, or .gif) 对应一个BitmapDrawable对象,XML中的根元素为<bitmap/>。 * Nine-Patch File 即我们常说的”点九图”,可以基于自动适应内容大小而伸缩区域的png图片,创建一个NinePatchDrawable对象。 * Layer List 用来管理多个drawable的数组,索引值最大的图层绘制在最上面,创建一个LayerDrawable对象,XML中的根元素为<layer-list/>。 * State List 用来根据不同的状态来引用不同的位图图形,创建一个StateListDrawable对象,XML中的根元素为<selector/>。 * Level List 一个LeveListDrawable管理着一组交替的drawable资源,level-list中某项的android:maxLevel数值大于或者等于setLevel设置的数值,就会被加载,创建一个LevelListDrawable对象,XML中的根元素为<level-list/>。。 * Transition Drawable 定义一个可以在两张图片资源之间实现淡入淡出效果的TransitionDrawable对象,XML中的根元素为<transition/>。 * Inset Drawable 定义一个根据指定的距离嵌入到另一个drawable的图片资源,创建一个TransitionDrawable对象,XML中的根元素为<inset/>。 * Clip Drawable 定义一个从当前drawable上截取一个”图片片段”的图片类型,创建一个ClipDrawable对象,XML中的根元素为<clip/>。 * Scale Drawable 定义一个基于当前的level,对当前drawable进行尺寸缩放后的drawable类型,XML中的根元素为<scale/>。 * Shape Drawable 定义一个包含颜色和渐变的几何图形,创建一个 ShapeDrawable对象,XML中的根元素为<shape/>。 * Animation Drawable 表示逐帧动画,xml中的根元素为<animation-list/> * 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类型提供的方法来处理。

在上面的分类中,BitmapNine-PatchState 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>

另外的几种类型将单独介绍。