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:ToolBar详解
android:ToolBar详解(手把手教程) 泡在网上的日子 发表于 2014-11-18 12:49 第 124857 次阅读 ToolBar 42 来源 http://blog.mosil.b ...
- Android之canvas详解
首先说一下canvas类: Class Overview The Canvas class holds the "draw" calls. To draw something, y ...
- 【转】Android Canvas绘图详解(图文)
转自:http://www.jcodecraeer.com/a/anzhuokaifa/androidkaifa/2012/1212/703.html Android Canvas绘图详解(图文) 泡 ...
- android屏幕适配详解
android屏幕适配详解 官方地址:http://developer.android.com/guide/practices/screens_support.html 一.关于布局适配建议 1.不要 ...
- Android Fragment用法详解(2)--动态添加Fragment
在上一篇文章<Android Fragment用法详解(1)--静态使用Fragment>我们讲解了Fragment的最简单的用法.这次我们来说一说Fragment复杂一丢丢的用法.在代码 ...
- Android 核心分析 之八Android 启动过程详解
Android 启动过程详解 Android从Linux系统启动有4个步骤: (1) init进程启动 (2) Native服务启动 (3) System Server,Android服务启动 (4) ...
- Android GLSurfaceView用法详解(二)
输入如何处理 若是开发一个交互型的应用(如游戏),通常需要子类化 GLSurfaceView,由此可以获取输入事件.下面有个例子: java代码: package eoe.ClearTes ...
- Android编译过程详解(一)
Android编译过程详解(一) 注:本文转载自Android编译过程详解(一):http://www.cnblogs.com/mr-raptor/archive/2012/06/07/2540359 ...
- Android.mk文件详解(转)
源:Android.mk文件详解 从对Makefile一无所知开始,折腾了一个多星期,终于对Android.mk有了一个全面些的了解.了解了标准的Makefile后,发现Android.mk其实是把真 ...
随机推荐
- spring的@Transactional(rollbackFor=Exception.class)的使用
Spring框架的事务基础架构代码将默认地只在抛出运行时和unchecked exceptions时才标识事务回滚. 也就是说,当抛出个RuntimeException 或其子类例的实例时.(Erro ...
- 指尖大冒险H5小游戏
前些天看了一篇很赞的文章,又因为想学习phaser,所以有了这个案例,在线预览可以点下方链接. 本案例中,核心原理是按文章中所提到的内容制作,整体遵循"大道至简"的原则开发,其实是 ...
- 阿里云部署Node.js项目(CentOS)
Node.js 是一个基于 Chrome V8 引擎的 JavaScript 运行环境,用来方便地搭建快速的易于扩展的网络应用.Node.js 使用了一个事件驱动.非阻塞式 I/O 的模型,使其轻量又 ...
- HashMap和ConcurrentHashMap实现原理及源码分析
HashMap实现原理及源码分析 哈希表(hash table)也叫散列表,是一种非常重要的数据结构,应用场景及其丰富,许多缓存技术(比如memcached)的核心其实就是在内存中维护一张大的哈希表, ...
- spring cloud 入门系列二:使用Eureka 进行服务治理
服务治理可以说是微服务架构中最为核心和基础的模块,它主要用来实现各个微服务实例的自动化注册和发现. Spring Cloud Eureka是Spring Cloud Netflix 微服务套件的一部分 ...
- 拟将博客迁移到github
其实博客园网站速度挺快的, 但是markdown的显示没有github美观. 尤其是代码高亮这一块. 近日发现github pages + vue + github api + stackedit 能 ...
- Xcode中lldb的REPL调试方法
Xcode中lldb调试器有一个repl语句,可以用来模拟swift解释器的REPL行为,即Read Eval Print Loop. 在Xcode里随意打开程序,中断入调试器.在调试控制台中输入re ...
- 一个貌似比较吊的递归转换为loop--总算成功了.
class Stack(object): """ A class to hold arguements and state data. """ ...
- [ExtJS5学习笔记]第三十五节 sencha extjs 5 组件查询方法总结
一个UI前台组件肯定会比较多,我们通常习惯性的使用ID来获取需要操作的组件,但是这种方法是extjs推荐的么?有没有extjs推荐使用的获取组件的方法呢? 目录 目录 extjs的查询组件的API 查 ...
- Swift如何取得View所属的ViewController
从VC取得View很容易,但有些情况下我们需要从View反向获取VC. 不过在一些特殊的场合,Cocoa库帮我们想的很周到,比如在自定义View过渡动画的时候: func animateTransit ...