相逢意气为君饮,系马高楼垂柳边。这篇文章主要讲述android的Drawable详解相关的知识,希望能为你提供帮助。
Drawable简介
Drawable有很多种,
用来表示一种图像的概念,
但他们又不完全是图像,
他们是用过颜色构建出来的各种图像的表现形式。Drawable一般都是通过xml来定义的 ,
当然我们也可以通过代码来创建,
Drawable是一个抽象的类,
是所以Drawable的基类,
每个具体的Drawable都是它的子类,
如ShapeDrawable,BitmapDrwable等,
其结构如下图:

文章图片
Drawable的内部有两个重要的参数需要说明, getIntrinsicHeight 和 getIntrinsicWidth, 通过他们可以获取内部图片的高度和宽度, 但是并不是所以的Drawable都有内部宽和高, 比如一个颜色形成的Drawable就没有内部宽和高。
Drawable分类
Drawable种类繁多, 比如, BitmapDrawable,ShapeDrwable,LayerDrawable,StateListDrawable等, 这里就不一一列举了, 下面列出一些常用的做一下简单的介绍。
ColorDrawable
colorDrawable是最简单的Drawable, 它实际上是代表了单色可绘制区域, 它包装了一种固定的颜色, 当ColorDrawable被绘制到画布的时候会使用颜色填充Paint, 在画布上绘制一块单色的区域。
在xml文件中使用color作为根节点来创建ColorDrawable, 它只有一个android:color属性, 通过它来决定ColorDrawable的颜色.
<
?xml version=
"
1.0"
encoding=
"
utf-8"
?>
<
color xmlns:android=
"
http://schemas.android.com/apk/res/android"
android:color=
"
#FF0000"
/>
当然, 我们也可以通过代码来创建, 不过需要注意的是习惯使用十六进制格式的数据表示颜色值。
ColorDrawable drawable =
new ColorDrawable(0xffff0000);
GradientDrawable
gradientDrawable表示一个渐变区域, 可以实现线性渐变、发散渐变和平铺渐变效果, 在Android中可以使用GradientDrawable表示很多复杂而又绚丽的界面效果。在xml文件中使用shape作为根节点来创建GradientDrawable, 它包含很多属性和子节点, 下面是GradientDrawable的xml文档节点结构。
<
?xml version=
"
1.0"
encoding=
"
utf-8"
?>
<
shape xmlns:android=
"
http://schemas.android.com/apk/res/android"
>
<
size />
//定义区域的大小
<
gradient>
//设置区域背景的渐变效果
<
solid/>
//设置区域的背景颜色,
如果设置了solid会覆盖gradient的效果
<
stroke />
//设置区域的边框效果
<
padding />
//设置区域的内边距
<
/shape>
BitmapDrawable
bitmapDrawable是对bitmap的一种包装, 它表示的就是一张图片, 我们可以通过xml方式来描述它。我们可以使用不同的属性含义来绘制他, 如Android: src,android.dither等。
<
?xml version=
"
1.0"
encoding=
"
utf-8"
?>
<
bitmap xmlns:android=
"
http://schemas.android.com/apk/res/android"
android:src=
"
@
drawable/png_icon_416"
android:tileMode=
"
mirror"
android:antialias=
"
true"
android:dither=
"
true"
>
<
/bitmap>
当然我们用代码也是可以实现的。
Bitmap mBitmap =
BitmapFactory.decodeResource(getResources(), R.drawable.png_icon_416);
BitmapDrawable mBitmapDrawable =
new BitmapDrawable(mBitmap);
mBitmapDrawable.setTileModeXY(TileMode.MIRROR, TileMode.MIRROR);
mBitmapDrawable.setAntiAlias(true);
mBitmapDrawable.setDither(true);
mDrawable =
mBitmapDrawable;
NinePatchDrawable
ninePatchDrawable用来表示一张.9格式的图片, 为了实现缩放不失真的效果。Android SDK工具集提供了处理点九图片的工具, 可以通过draw9patch.bat运行, 通过这个工具可以很容易把普通的PNG图片处理成“点九”图片。从它的名字也很容易理解“点九”图的含义, 其实相当于把一张PNG图分成了9个部分(九宫格), 分别为4个角, 4条边, 以及一个中间区域, 4个角是不做拉伸的, 所以还能一直保持圆角的清晰状态, 而2条水平边和2条垂直边分别只做水平和垂直拉伸, 所以不会出现边框被拉粗的情况, 只有中间用黑线指定的区域做拉伸, 通过这种处理方式图片才不会失真。如图6-5所示, 对4条黑线分别做了注释。左边和上边的黑线形成的矩形区域是图片的拉伸区域, 下边和右边形成的矩形区域是内容所在的区域。黑线可以是连续的也可以是不连续的, 不过为了达到最好的显示效果, 最好使用连续的黑线。
使用了*.9.png图片技术后, 只需要采用一套界面切图去适配不同的分辨率, 而且大幅减少安装包的大小。

文章图片
对于创建ninePatchDrawable也是极其简单的。
<
?xml version=
"
1.0"
encoding=
"
utf-8"
?>
<
nine-patch
xmlns:android=
"
http://schemas.android.com/apk/res/android"
android:src=
"
@
drawable/droid_logo"
android:dither=
"
true"
/>
Android虽然可以使用java代码创建NinePatchDrawable, 但是极少情况会那么做, 主要的原因是由于Android SDK会在编译工程时对点九图片进行编译, 形成特殊格式的图片。使用代码创建NinePatchDrawable时只能针对编译过的点九图片资源, 对于没有编译过的点九图片资源都当做BitmapDrawable对待。在使用点九图片时需要注意的是, 点九图只能适用于拉伸的情况, 对于压缩的情况并不适用, 如果需要适配很多分辨率的屏幕时需要把点九图做的小一点。
ClipDrawable
clipDrawable听名字就是对Drawable进行裁剪的。android中的进度条就是使用一个ClipDrawable实现效果的, 它根据level的属性值, 决定剪切区域的大小。
需要注意的是ClipDrawable是根据level的大小控制图片剪切操作的, level大小从0到10000。
<
?xml version=
"
1.0"
encoding=
"
utf-8"
?>
<
clip xmlns:android=
"
http://schemas.android.com/apk/res/android"
android:clipOrientation=
"
horizontal"
android:drawable=
"
@
drawable/bitmap_android"
android:gravity=
"
left"
>
<
/clip>
需要注意的是如果没有android:drawable属性, 必须要设置一个任意类型的drawable作为子节点。
<
?xml version=
"
1.0"
encoding=
"
utf-8"
?>
<
clip xmlns:android=
"
http://schemas.android.com/apk/res/android"
android:clipOrientation=
"
horizontal"
android:gravity=
"
left"
>
<
bitmap
android:src=
"
@
drawable/android_text"
android:gravity=
"
center"
/>
<
/clip>
AnimationDrawable
animationDrawable就是动画的, 这个是按帧播放的那种。使用起来也非常简单, 在xml文件中使用animation-list作为根节点定义AnimationDrawable, 使用item设置需要播放的每一帧使用的drawable资源, 以及每一帧持续的时间即可。
<
?xml version=
"
1.0"
encoding=
"
utf-8"
?>
<
animation-list xmlns:android=
"
http://schemas.android.com/apk/res/android"
android:oneshot=
"
false"
>
<
item
android:drawable=
"
@
drawable/level1"
android:duration=
"
300"
/>
<
item
android:drawable=
"
@
drawable/level2"
android:duration=
"
300"
/>
<
item
android:drawable=
"
@
drawable/level3"
android:duration=
"
300"
/>
<
item
android:drawable=
"
@
drawable/level4"
android:duration=
"
300"
/>
<
item
android:drawable=
"
@
drawable/level5"
android:duration=
"
300"
/>
<
/animation-list>
代码实现, 定义了AnimationDrawable之后需要主动调用AnimationDrawable的start播放动画, 需要注意的是, 当我们在Activity的oncreate方法中调用start方法时会没有任何效果, 那是因为view还没有完成初始化, 所以正确的使用方法是。
mHandler.postDelayed(new Runnable() {
@
Override
public void run() {
// TODO Auto-generated method stub
((AnimationDrawable)mDrawable).start();
}
}, 1000);
LayerDrawable
layerDrawable顾名思义就是处于不同的层的, 管理一组drawable, 每个drawable都处于不同的层, 当它们被绘制的时候, 按照顺序全部都绘制到画布上。虽然有时候可能出现交错的情况, 但是由于位于不同的层, 显示上 也是不会有任何影响的。
<
?xml version=
"
1.0"
encoding=
"
utf-8"
?>
<
layer-list xmlns:android=
"
http://schemas.android.com/apk/res/android"
>
<
item android:drawable=
"
@
drawable/layer1"
/>
<
item android:drawable=
"
@
drawable/layer2"
/>
<
item android:drawable=
"
@
drawable/layer3"
/>
<
/layer-list>
LevelListDrawable
levelDrawable的每一个drawable都对应一个level范围, 当它们被绘制的时候, 根据level属性值选取对应的一个drawable绘制到画布上。就像波浪线一样。
<
?xml version=
"
1.0"
encoding=
"
utf-8"
?>
<
level-list xmlns:android=
"
http://schemas.android.com/apk/res/android"
>
<
item
android:maxLevel=
"
2000"
android:drawable=
"
@
drawable/level1"
/>
<
item
android:maxLevel=
"
4000"
android:drawable=
"
@
drawable/level2"
/>
<
item
android:maxLevel=
"
6000"
android:drawable=
"
@
drawable/level3"
/>
<
/level-list>
StateListDrawable
stateListDrawable管理一组drawable, 每一个drawable都对应着一组状态, 状态的选择类似于java中的switch-case组合, 按照顺序比较状态, 当遇到匹配的状态后, 就返回对应的drawable, 因此需要把最精确的匹配放置在最前面, 按照从精确到粗略的顺序排列。这也是我们开发中用的最多的, 写背景选择器的时候, 我们一般只会使用两种状态, 其实它可以表示很多种状态, 几乎可以实现很多效果。
<
?xml version=
"
1.0"
encoding=
"
utf-8"
?>
<
selector xmlns:android=
"
http://schemas.android.com/apk/res/android"
>
<
item android:state_focused=
"
false"
android:state_pressed=
"
false"
android:drawable=
"
@
drawable/gradient_normal"
/>
<
item android:state_pressed=
"
true"
android:drawable=
"
@
drawable/gradient_pressed"
/>
<
item android:state_focused=
"
true"
android:drawable=
"
@
drawable/gradient_focused"
/>
<
/selector>
其实还有些Drawable, 这里就不一一讲解了。
【android的Drawable详解】
推荐阅读
- Android性能优化之TraceView和Lint使用详解
- android dataBinding详解
- Word2007插入题注技巧之图片题注_Word专区
- Word2007:灵活运用书签技巧准确定位_Word专区
- Word2007:插入交叉引用的设置_Word专区
- 在word2010输入公式符号的窍门_Word专区
- Word2010:添加时间与日期的技巧_Word专区
- Word2010:插入文本框的秘籍_Word专区
- Word2010中对齐方式的详细说明_Word专区