Android把可绘制的对象抽象为Drawable,不同的图形图像资源就代表着不同的drawable类型。Android FrameWork提供了一些具体的Drawable实现,通常在代码中都不会直接接触Drawable的实现类。

在实际的开发过程中,会把使用到的资源都放置在res/drawable目录,剩下的工作交给Android SDK 就行了,当需要使用图片资源的时候,可以使用@drawable标志在xml中引用drawable资源就行,也可以在代码中使用id引用这些drawable资源。

在使用drawable资源的时,有一点需要注意,drawable默认是内存共享的,也就说在不同的地方使用了同一个drawable,它们都指向相同的资源,而且具有相同的状态,如果在一个地方修改了这个drawable,所有使用它的地方都会改变。

Android内置了如下几种Drawable类型:ColorDrawable、GradientDrawable、BitmapDrawable、 NinePatchDrawable、InsetDrawable、ClipDrawable、ScaleDrawable、RotateDrawable、AnimationDrawable、LayerDrawable、LevelListDrawable、StateListDrawable、TransitionDrawable。

除了这些预置的drawable实现类以外,也可以自定义drawable的实现类型,大部分情况都不需要自定义drawable类型,使用系统提供的这些drawable实现类型已经覆盖了很多情况。在实际的编程过程中也很少会接触这些具体drawable实现类型,因为编写android应用程序使用xml可以很容易的创建drawable,只有在程序中需要修改drawable的属性时,才需要使用具体的drawable类型提供的方法来处理。下面就来逐个认识这些Drawable类型。

一、ColorDrawable

ColorDrawable 是最简单的Drawable,它实际上是代表了单色可绘制区域,它包装了一种固定的颜色,当ColorDrawable被绘制到画布的时候会使用颜色填充Paint,在画布上绘制一块单色的区域。

在xml文件中使用color作为根节点来创建ColorDrawable,它只有一个android:color属性,通过它来决定ColorDrawable的颜色,Android并没有提供修改这个颜色值的Api,所以这个颜色一旦设置之后,就不能直接修改了。

下面的xml文件定义了一个颜色为红色的ColorDrawable:

1 <?xml version="1.0" encoding="utf-8"?>
2 <color xmlns:android="http://schemas.android.com/apk/res/android"
3 android:color="#FF0000" />

当然也可以使用Java代码创建ColorDrawable,需要注意的是Android中使用一个int类型的数据表示颜色值,通常习惯使用十六进制格式的数据表示颜色值。一个int类型包含四个字节,分别代表颜色的4个组成部分:透明度(Alpha)、红(RED)、绿(GREEN)、蓝(BLUE),每个部分由一个字节(8个bit)表示,取值范围为0~255。在xml中使用颜色时可以省略透明度(Alpha)部分,如#ff0000表示红色。但是在代码中必须要明确指出透明度(Alpha)代表的数据,如果省略了就表示完全透明的颜色,例如0xFFFF0000表示红色,而0xFF0000虽然也表示红色,但它却是完全透明的,也就是说当绘制到画布上时,看不出有任何效果。

使用Java代码也可以创建ColorDrawable,代码如下:

1         ColorDrawable drawable = new ColorDrawable(0xffff0000);

二、GradientDrawable

GradientDrawable 表示一个渐变区域,可以实现线性渐变、发散渐变和平铺渐变效果,在Android中可以使用GradientDrawable表示很多复杂而又绚丽的界面效果。

可以使用xml定义GradientDrawable,相对于ColorDrawable类型,GradientDrawable要复杂很多,它有很多的元素组成。在xml文件中使用shape作为根节点来创建GradientDrawable,它包含很多属性和子节点,下面是GradientDrawable的xml文档节点结构。

1 <?xml version="1.0" encoding="utf-8"?>
2 <shape xmlns:android="http://schemas.android.com/apk/res/android">
3         <size /> //定义区域的大小
4         <gradient>//设置区域背景的渐变效果
5         <solid/>//设置区域的背景颜色,如果设置了solid会覆盖gradient的效果
6         <stroke />//设置区域的边框效果
7         <padding />//设置区域的内边距
8 </shape>

其中每个节点都有许多属性需要设置,以达到不同的渐变效果。

以下是几种不同渐变效果实现的xml文件代码:

01 <!-- 线性渐变效果的椭圆-->
02 <?xml version="1.0" encoding="utf-8"?>
03 <shape
04     xmlns:android="http://schemas.android.com/apk/res/android"
05     android:shape="oval">
06  
07     <gradient
08         android:startColor="#ff0000"
09         android:centerColor="#00ff00"
10         android:endColor="#0000ff"
11         android:angle="90" />
12     <stroke
13         android:width="3dip"
14         android:color="#fff"
15         android:dashWidth="4dip"
16         android:dashGap="5dip" />
17 </shape>
18  
19 <!-- 平铺渐变效果的圆环-->
20 <?xml version="1.0" encoding="utf-8"?>
21 <shape xmlns:android="http://schemas.android.com/apk/res/android"
22         android:shape="ring" android:innerRadiusRatio="8"
23         android:thicknessRatio="3" android:useLevel="false">
24         <gradient android:type="sweep" android:useLevel="false"
25                 android:startColor="#ff0000" android:endColor="#0000ff"android:centerColor="#00ff00"/>
26 </shape>
27  
28 <!-- 发散渐变效果的圆-->
29 <?xml version="1.0" encoding="utf-8"?>
30 <shape xmlns:android="http://schemas.android.com/apk/res/android"
31         android:shape="ring" android:innerRadius="0dip"
32         android:thickness="70dip" android:useLevel="false">
33         <gradient android:type="radial" android:useLevel="false"android:gradientRadius="70"
34                 android:startColor="#ff0000" android:endColor="#0000ff"android:centerColor="#00ff00"/>
35 </shape>

以下几幅图展示了上述三个渐变效果:

<ignore_js_op>

图6-1  线性渐变效果的椭圆

<ignore_js_op>

图6-2  平铺渐变效果的圆环

<ignore_js_op>

图6-3  发散渐变效果的圆

三、BitmapDrawable

BitmapDrawable 是对bitmap的一种包装,可以设置它包装的bitmap在BitmapDrawable区域内的绘制方式,如平铺填充、拉伸填充或者保持图片原始大小,也可以在BitmapDrawable区域内部使用gravity指定的对齐方式。

在xml文件中使用bitmap作为根节点来定义BitmapDrawable, 下面列出了bitmap节点的所有属性。

下面的xml代码定义一个BitmapDrawable,同时设置了BitmapDrawable的tileMode 属性为mirror,通过这样设置会使用小图片在水平和竖直方向做镜面平铺效果。

1 <?xml version="1.0" encoding="utf-8"?>
2 <bitmap xmlns:android="http://schemas.android.com/apk/res/android"
3     android:src="@drawable/png_icon_416"
4     android:tileMode="mirror"
5     android:antialias="true"
6     android:dither="true"
7     >
8 </bitmap>

也可以使用Java代码实现相同的效果,等价的Java代码如下:

1 Bitmap mBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.png_icon_416);
2 BitmapDrawable mBitmapDrawable = new BitmapDrawable(mBitmap);
3 mBitmapDrawable.setTileModeXY(TileMode.MIRROR, TileMode.MIRROR);
4 mBitmapDrawable.setAntiAlias(true);
5 mBitmapDrawable.setDither(true);
6 mDrawable = mBitmapDrawable;

效果如下图所示:

<ignore_js_op>

图6-4  BitmapDrawable运行效果图

四、NinePatchDrawable

NinePatchDrawable,“点九图”是Andriod平台的一种特殊的图片格式,文件扩展名为:.9.png。支持Android平台的手机类型很多,有多种不同的分辨率,很多控件的切图文件在被放大拉伸后,边角会模糊失真。在android平台下使用“点九”图片处理技术,可以将图片横向和纵向同时进行拉伸,以实现在多分辨率下的完美显示效果。点九图片在拉伸时仍能保留图像的渐变质感和圆角的精细度。

Android SDK工具集提供了处理点九图片的工具,可以通过draw9patch.bat运行,通过这个工具可以很容易把普通的PNG图片处理成“点九”图片。从它的名字也很容易理解“点九”图的含义,其实相当于把一张PNG图分成了9个部分(九宫格),分别为4个角,4条边,以及一个中间区域,4个角是不做拉伸的,所以还能一直保持圆角的清晰状态,而2条水平边和2条垂直边分别只做水平和垂直拉伸,所以不会出现边框被拉粗的情况,只有中间用黑线指定的区域做拉伸,通过这种处理方式图片才不会失真。如图6-5所示,对4条黑线分别做了注释。左边和上边的黑线形成的矩形区域是图片的拉伸区域,下边和右边形成的矩形区域是内容所在的区域。黑线可以是连续的也可以是不连续的,不过为了达到最好的显示效果,最好使用连续的黑线。

<ignore_js_op>

图6-5  点九图片示意图

使用了*.9.png图片技术后,只需要采用一套界面切图去适配不同的分辨率,而且大幅减少安装包的大小。Android FrameWork在显示点九图片时使用了高效的优化算法,所示应用程序不需要专门做处理就可以实现图片拉伸自适应,减少了代码量和实际开发的工作量。

在xml文件中使用使用nine-patch作为根节点创建NinePatchDrawable。同时,也可以使用bitmap包装点九图片,android FrameWork会根据android:src属性设置的图片类型来生成对应的drawable。代码如下:

1 <?xml version="1.0" encoding="utf-8"?>
2 <nine-patch
3     xmlns:android="http://schemas.android.com/apk/res/android"
4     android:src="@drawable/droid_logo"
5     android:dither="true" />
1 <?xml version="1.0" encoding="utf-8"?>
2 <bitamp
3     xmlns:android="http://schemas.android.com/apk/res/android"
4     android:src="@drawable/droid_logo"
5     android:dither="true" />

下面看一下原始点九图片以及拉伸之后的效果:

<ignore_js_op>

图6-6  原始点九图片

<ignore_js_op>

图6-7  点九图片拉伸之后的效果

最后,需要指出的是,Android虽然可以使用Java代码创建NinePatchDrawable,但是极少情况会那么做,主要的原因是由于Android SDK会在编译工程时对点九图片进行编译,形成特殊格式的图片。使用代码创建NinePatchDrawable时只能针对编译过的点九图片资源,对于没有编译过的点九图片资源都当做BitmapDrawable对待。在使用点九图片时需要注意的是,点九图只能适用于拉伸的情况,对于压缩的情况并不适用,如果需要适配很多分辨率的屏幕时需要把点九图做的小一点。

五、InsetDrawable

InsetDrawable 表示一个drawable嵌入到另外一个drawable内部,并且在内部留一些间距,这一点很像drawable的padding属性,区别在于 padding表示drawable的内容与drawable本身的边距,insetDrawable表示两个drawable和容器之间的边距。当控件需要的背景比实际的边框小的时候比较适合使用InsetDrawable。

在xml文件中使用inset作为跟节点定义InsetDrawable。

下面的xml定义了一个四边边距都为20dip的InsetDrawable,代码如下:

1 <?xml version="1.0" encoding="utf-8"?>
2 <inset xmlns:android="http://schemas.android.com/apk/res/android"
3     android:drawable="@drawable/bitmap_bell"
4     android:insetLeft="20dp"
5     android:insetRight="20dp"
6     android:insetTop="20dp"
7     android:insetBottom="20dp"
8     >
9 </inset>

效果如下图所示:

<ignore_js_op>

图6-8  InsetDrawable运行效果图

六、ClipDrawable

ClipDrawable 是对一个Drawable进行剪切操作,可以控制这个drawable的剪切区域,以及相相对于容器的对齐方式,android中的进度条就是使用一个ClipDrawable实现效果的,它根据level的属性值,决定剪切区域的大小。

在xml文件中使用clip作为根节点定义ClipDrawable。

需要注意的是ClipDrawable是根据level的大小控制图片剪切操作的,官方文档的note中提到:The drawable is clipped completely and not visible when the level is 0 and fully revealed when the level is 10,000。也就是level的大小从0到10000,level为0时完全不显示,为10000时完全显示。是用Drawable提供的setLevel(int level)方法来设置剪切区域。

下面为定义ClipDrawable的代码:

1 <?xml version="1.0" encoding="utf-8"?>
3     android:clipOrientation="horizontal"
4     android:drawable="@drawable/bitmap_android"
5     android:gravity="left"
6     >
7 </clip>

如果没有android:drawable属性,必须要设置一个任意类型的drawable作为子节点,代码如下:

01 <?xml version="1.0" encoding="utf-8"?>
02 <clip xmlns:android="http://schemas.android.com/apk/res/android"
03     android:clipOrientation="horizontal"
04     android:gravity="left"
05     >
06     <bitmap
07         android:src="@drawable/android_text"
08         android:gravity="center"
09         />
10 </clip>

效果如下图所示:

<ignore_js_op>

图6-9  ClipDrawable运行效果图

Android中Drawable分类汇总(上)的更多相关文章

  1. GitHub上史上最全的Android开源项目分类汇总 (转)

    GitHub上史上最全的Android开源项目分类汇总 标签: github android 开源 | 发表时间:2014-11-23 23:00 | 作者:u013149325 分享到: 出处:ht ...

  2. GitHub上史上最全的Android开源项目分类汇总

    今天在看博客的时候,无意中发现了 @Trinea 在GitHub上的一个项目 Android开源项目分类汇总 ,由于类容太多了,我没有一个个完整地看完,但是里面介绍的开源项目都非常有参考价值,包括很炫 ...

  3. Android 开源项目分类汇总(转)

    Android 开源项目分类汇总(转) ## 第一部分 个性化控件(View)主要介绍那些不错个性化的 View,包括 ListView.ActionBar.Menu.ViewPager.Galler ...

  4. Android 开源项目分类汇总

    Android 开源项目分类汇总 Android 开源项目第一篇——个性化控件(View)篇  包括ListView.ActionBar.Menu.ViewPager.Gallery.GridView ...

  5. Android开源项目分类汇总【畜生级别】[转]

    Android开源项目分类汇总 欢迎大家推荐好的Android开源项目,可直接Commit或在 收集&提交页 中告诉我,欢迎Star.Fork :) 微博:Trinea    主页:www.t ...

  6. Android开源项目分类汇总[转]

    Android开源项目分类汇总 如果你也对开源实现库的实现原理感兴趣,欢迎 Star 和 Fork Android优秀开源项目实现原理解析欢迎加入 QQ 交流群:383537512(入群理由需要填写群 ...

  7. Android开源项目分类汇总【畜生级别】

    From :http://blog.csdn.net/forlong401/article/details/25459403?c=6c4cd677a617db4655988e41ee081691#t7 ...

  8. Android开源项目分类汇总-转载

    太长了,还是转载吧...今天在看博客的时候,无意中发现了@Trinea在GitHub上的一个项目Android开源项目分类汇总,由于类容太多了,我没有一个个完整地看完,但是里面介绍的开源项目都非常有参 ...

  9. Excel-返回列表或数据库中的分类汇总(汇总可以实现要还是不要统计隐藏行功能) subtotal()

    SUBTOTAL函数 函数名称:SUBTOTAL 主要功能:返回列表或数据库中的分类汇总. 使用格式:SUBTOTAL(function_num, ref1, ref2, ...) 参数说明:Func ...

随机推荐

  1. BZOJ 1856: [Scoi2010]字符串( 组合数 )

    求(0,0)->(n,m)且在直线y=x下方(可以在y=x上)的方案数...同 http://www.cnblogs.com/JSZX11556/p/4908648.html --------- ...

  2. 移除Strorefront站点footer上的Storefront Design By WooThemes字样

    进入wp-content\themes\storefront\inc\structure\footer.php, 注释掉代码: if ( ! function_exists( 'storefront_ ...

  3. 【原创】MapGIS K9 三维二次开发入门

    开发语言:C# 平台版本:MapGIS K9 SP3 MapGIS K9三维平台也提供了接口和组件以实现二次开发.用户可以根据提供的接口和组件进行二次开发,也可以借助MapGISK9数据中心框架,可以 ...

  4. javascript定义函数不同方式的区别

    学习javascript中遇到了这么一个问题,代码如下: var test = 'a'; function test() { alert('Hello World!'); } alert(test); ...

  5. F#实现的单链表(函数式的思想)

    // 在 http://fsharp.net 上了解有关 F# 的更多信息 // 请参阅“F# 教程”项目以获取更多帮助. type list = | Nil | Cons of int * list ...

  6. ZOJ 1825 compoud words

    题目大意:输入一串递增的单词序列,需要找出符合条件的单词递增输出,条件是:将一个单词拆成左右两个单词后,能在输入中找到这两个单词.例如单词 alien,可以拆成 a 和 lien,而输入中刚好同时有a ...

  7. Android 5.0五大安全特性

    全盘加密(Full Disk Encryption, FDE) 对所有闪存数据加密.性能下降较大 Nexus 6,Nexus 9无法关闭FDE 对于其它设备.Google推荐开启 多用户支持 4.2中 ...

  8. android -- 蓝牙 bluetooth (四)OPP文件传输

    在前面android -- 蓝牙 bluetooth (一) 入门文章结尾中提到了会按四个方面来写这系列的文章,前面已写了蓝牙打开和蓝牙搜索,这次一起来看下蓝牙文件分享的流程,也就是蓝牙应用opp目录 ...

  9. 简单仿京东导航下拉菜单 javascript

    <html xmlns="http://www.w3.org/1999/xhtml"><head runat="server">    ...

  10. 非root不能gdb attach的限制

    Could not attach to process.  If your uid matches the uid of the targetprocess, check the setting of ...