Android--各种Drawable介绍
来源:互联网 发布:北京seo外包公司 编辑:程序博客网 时间:2024/05/20 06:29
Drawable 是什么
这篇博客我们要讲得是关于 Drawable 的知识。Drawable 是Android给我们的一个抽象类,是对可绘制物体的抽象。与 View 不同的是 Drawable 没有事件和交互方法。Drawable 不是直接面向我们,是看不见的,不能为它添加点击事件。
一个Drawable对象是“那些能够在其上面图画的任意对象”,它也许是一个bitmap对象,也可能是一个solid color、一个其他Drawable对象的集合,亦或是某种结构。 大多数Android UI框架喜欢用Drawable对象,而不是Bitmap对象。一个View可以接受任何Drawable对象作为background,一个Imageview可以显示Drawable前景对象;作为资源的 Images 一般加载为Drawable对象。Drawable并没有实际的宽和高,一般作为 View 的背景时,Drawable就会被拉伸到 View 的大小。
BitmapDrawable
BitmapDrawable:是对 bitmap 的一种包装,可以设置它包装的 bitmap 在 BitmapDrawable 区域内的绘制方式,如平铺填充、拉伸填充或者保持图片原始大小,也可以在 BitmapDrawable 区域内部使用 gravity 指定的对齐方式。
在xml文件中使用 bitmap 作为根节点来定义 BitmapDrawable。
下面的xml代码定义一个BitmapDrawable,同时设置了 BitmapDrawable的tileMode 属性为 mirror,通过这样设置会使得小图片在水平和竖直方向做镜面平铺效果。
<?xml version="1.0" encoding="utf-8"?><bitmap xmlns:android="http://schemas.android.com/apk/res/android" android:src="@drawable/ic_launcher" android:tileMode="mirror" android:antialias="true" android:dither="true"></bitmap>
用 Java 实现同样效果:
Bitmap mBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.ic_launcher);BitmapDrawable mBitmapDrawable = new BitmapDrawable(mBitmap);mBitmapDrawable.setTileModeXY(Shader.TileMode.MIRROR, Shader.TileMode.MIRROR);mBitmapDrawable.setAntiAlias(true);mBitmapDrawable.setDither(true);
如果BitmapDrawable 依附的是 match_parent 的 View,则会像镜子铺满整个控件。
ClipDrawable
ClipDrawable 是对一个Drawable进行剪切操作,可以控制这个drawable的剪切区域,以及相对于容器的对齐方式,android中的进度条就是使用一个ClipDrawable实现效果的,它根据level的属性值,决定剪切区域的大小。
在xml文件中使用clip作为根节点定义ClipDrawable。
需要注意的是ClipDrawable是根据level的大小控制图片剪切操作的,level的大小从0到10000,level为0时完全不显示,为10000时完全显示。是用 Drawable 提供的 setLevel 方法来设置剪切区域。
下面为定义ClipDrawable的代码:
<?xml version="1.0" encoding="utf-8"?><clip xmlns:android="http://schemas.android.com/apk/res/android" android:drawable="@drawable/ic_launcher" android:clipOrientation="horizontal" android:gravity="left"></clip>
public class ClipDrawableActivity extends Activity { private ImageView iv; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_clip); iv = (ImageView) findViewById(R.id.iv); ClipDrawable drawable = (ClipDrawable) iv.getDrawable(); drawable.setLevel(5000);//0~10000 }}
如图所示,如果 gravity 为right,则从右边开始显示,这个图片显示右半边;如果clipOrientation 为 vertical,则垂直显示,这个图片显示上半边。
ColorDrawable
ColorDrawable 是最简单的Drawable,它实际上是代表了单色可绘制区域,它包装了一种固定的颜色,当ColorDrawable被绘制到画布的时候会使用颜色填充Paint,在画布上绘制一块单色的区域。
在xml文件中使用 color 作为根节点来创建ColorDrawable,它只有一个android:color属性,通过它来决定ColorDrawable的颜色,Android并没有提供修改这个颜色值的Api,所以这个颜色一旦设置之后,就不能直接修改了。
下面的xml文件定义了一个颜色为红色的ColorDrawable:
<?xml version="1.0" encoding="utf-8"?><color xmlns:android="http://schemas.android.com/apk/res/android" 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,代码如下:
ColorDrawable drawable = new ColorDrawable(0xffff0000);
DrawableContainer
StateListDrawable
StateListDrawable管理一组drawable,每一个drawable都对应着一组状态,状态的选择类似于 Java 中的 switch-case 组合,按照顺序比较状态,当遇到匹配的状态后,就返回对应的drawable,因此需要把最精确的匹配放置在最前面,按照从精确到粗略的顺序排列。
StateListDrawable在Android中使用的非常广泛,所有控件的背景基本上都使用了StateListDrawable,比如按钮就具有很多状态,按下状态、选中状态、默认状态、禁用状态等等,像这样在不用的状态下显示效果不一样的时候,就是需要使用StateListDrawable的时候。
在xml文件中使用selector作为根节点来定义StateListDrawable,并使用item定义不同状态下的drawable。
创建StateListDraw的代码如下:
<?xml version="1.0" encoding="utf-8"?><selector xmlns:android="http://schemas.android.com/apk/res/android"> <item android:state_pressed="true" android:drawable="@drawable/on"/> <item android:drawable="@drawable/off"/></selector>
LevelListDrawable
管理一组drawable,每一个drawable都对应一个level范围,当它们被绘制的时候,根据level属性值选取对应的一个drawable绘制到画布上。
在xml文件中使用level-list作为根节点来定义LevelListDrawable,通过item子节点定义每一层的drawable,level-list没有属性节点,只包含item子节点。
调用Drawable中的 setLevel() 方法可以加载level-list或代码中定义的某个Drawable资源。
创建LevelListDrawable的代码如下:
<?xml version="1.0" encoding="utf-8"?><level-list xmlns:android="http://schemas.android.com/apk/res/android" > <item android:drawable="@drawable/off" android:minLevel="6" android:maxLevel="10"></item> <item android:drawable="@drawable/on" android:minLevel="12" android:maxLevel="20"></item></level-list>
public class LevelListDrawableActivity extends Activity { private ImageView iv; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_level); iv = (ImageView) findViewById(R.id.iv); iv.setImageLevel(8); } public void lampOn(View v) { iv.setImageLevel(15); } public void lampOff(View v) { iv.setImageLevel(8); }}
AnimationDrawable
AnimationDrawable 对应于Android中的帧动画,就是把一系列的drawable按照一定的顺序,一帧一帧的播放,并且可以使用android:oneshot属性设置是否循环播放。
在xml文件中使用animation-list作为根节点定义AnimationDrawable,使用item设置需要播放的每一帧使用的drawable资源,以及每一帧持续的时常。我们为view设置Drawable资源,可以在代码中用setBackgroundResource()或者在xml中设置 Image 的背景。
下面的代码定义了一个包含三帧的AnimationDrawable,帧间隔为1000毫秒,代码如下:
<?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/ic_launcher" android:duration="1000" /> <item android:drawable="@drawable/gradient" android:duration="1000" /> <item android:drawable="@drawable/gradient2" android:duration="1000" /></animation-list>
public class AnimationDrawableActivity extends Activity { private ImageView iv; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_animation); iv = (ImageView) findViewById(R.id.iv); AnimationDrawable drawable = (AnimationDrawable) iv.getBackground(); drawable.start(); }}
GradientDrawable
GradientDrawable 表示一个渐变区域,可以实现线性渐变、发散渐变和平铺渐变效果,在Android中可以使用GradientDrawable表示很多复杂而又绚丽的界面效果。
可以使用xml定义GradientDrawable,相对于ColorDrawable类型,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>
线性渐变效果的椭圆:
<?xml version="1.0" encoding="utf-8"?><!--线性渐变效果的椭圆--><shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="oval"> <gradient android:angle="90" android:centerColor="#00ff00" android:endColor="#0000ff" android:startColor="#ff0000" /> <stroke android:width="3dip" android:color="#fff" android:dashGap="5dip" android:dashWidth="4dip" /></shape>
平铺渐变效果的圆环:
<?xml version="1.0" encoding="utf-8"?><!--平铺渐变效果的圆环--><shape xmlns:android="http://schemas.android.com/apk/res/android" android:innerRadiusRatio="8" android:shape="ring" android:thicknessRatio="3" android:useLevel="false"> <gradient android:centerColor="#00ff00" android:endColor="#0000ff" android:startColor="#ff0000" android:type="sweep" android:useLevel="false" /></shape>
发散渐变效果的圆:
<?xml version="1.0" encoding="utf-8"?><!--发散渐变效果的圆--><shape xmlns:android="http://schemas.android.com/apk/res/android" android:innerRadius="0dip" android:shape="ring" android:thickness="70dip" android:useLevel="false"> <gradient android:centerColor="#00ff00" android:endColor="#0000ff" android:gradientRadius="70" android:startColor="#ff0000" android:type="radial" android:useLevel="false" /></shape>
InsetDrawable
InsetDrawable 表示一个drawable嵌入到另外一个drawable内部,并且在内部留一些间距,这一点很像drawable的padding属性,区别在于 padding表示drawable的内容与drawable本身的边距,insetDrawable表示两个drawable和容器之间的边距。当控件需要的背景比实际的边框小的时候比较适合使用InsetDrawable。
在xml文件中使用inset作为根节点定义InsetDrawable。
代码如下:
<?xml version="1.0" encoding="utf-8"?><inset xmlns:android="http://schemas.android.com/apk/res/android" android:drawable="@drawable/brightness" android:insetLeft="20dp" android:insetRight="20dp" android:insetTop="90dp" android:insetBottom="90dp"></inset>
在LinearLayout 中设置为背景。
因为模拟器上的宽高不一样,所以如果inse都设置为同一个值,那么这个图形就会变形。
LayerDrawable
LayerDrawable 管理一组drawable,每个drawable都处于不同的层,当它们被绘制的时候,按照顺序全部都绘制到画布上,列表的最后一个在最上层。虽然这些drawable会有交差或者重叠的区域,但是它们是位于不同的层,彼此之间不会影响。
在xml文件中使用 layer-list 作为根节点来定义LayerDrawable,通过item子节点定义每一层的drawable,layer-list没有属性节点,只包含item子节点。
下面的xml定义了一个两层的LayerDrawable,代码如下:
<?xml version="1.0" encoding="utf-8"?><layer-list xmlns:android="http://schemas.android.com/apk/res/android" > <item android:top="50dp" android:left="20dp"> <bitmap android:src="@drawable/ic_launcher" android:gravity="center"/> </item> <item android:top="30dp" android:left="0dp"> <bitmap android:src="@drawable/ic_launcher" android:gravity="center"/> </item></layer-list>
可以很清楚的看出第二个item覆盖在第一个item上。
TransitionDrawable
TransitionDrawable 是LayerDrawable的子类,不过它只负责管理两层drawable,并且提供了一个透明度变化的动画,可以控制从一层drawable过度到另外一层drawable的动画效果。
在xml文件中使用transition作为根节点来定义TransitionDrawable,通过item子节点定义两层使用的drawable。第一个item就为默认的资源,startTransition() 就是第一个item到第二个item的过程,endTransition则是反过来。
创建TransitionDrawable的代码如下:
<?xml version="1.0" encoding="utf-8"?><transition xmlns:android="http://schemas.android.com/apk/res/android" > <item android:drawable="@drawable/off"></item> <item android:drawable="@drawable/on"></item></transition>
public class TransitionDrawableActivity extends Activity { private ImageView iv; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_transition); iv = (ImageView) findViewById(R.id.iv); } public void lampOn(View v) { TransitionDrawable drawable = (TransitionDrawable) iv.getDrawable(); drawable.startTransition(3000); } public void lampOff(View v) { TransitionDrawable drawable = (TransitionDrawable) iv.getDrawable(); drawable.reverseTransition(3000); }}
在使用TransitionDrawable的时,需要主动调用startTransition方法启动两个层之间的切换动画,也可以调用reverseTransition方法启动逆向切换动画,它们都可以接受一个毫秒数,作为动画的持续时间。
NinePatchDrawable
NinePatchDrawable,“点九图”是Andriod平台的一种特殊的图片格式,文件扩展名为:.9.png。支持Android平台的手机类型很多,有多种不同的分辨率,很多控件的切图文件在被放大拉伸后,边角会模糊失真。在android平台下使用“点九”图片处理技术,可以将图片横向和纵向同时进行拉伸,以实现在多分辨率下的完美显示效果。点九图片在拉伸时仍能保留图像的渐变质感和圆角的精细度。
Android 中如何使用 .9图片,我在Android屏幕适配这篇博客中有提,有兴趣的可以去看。
在xml文件中使用使用nine-patch作为根节点创建NinePatchDrawable。同时,也可以使用bitmap包装点九图片,android FrameWork会根据android:src属性设置的图片类型来生成对应的drawable。代码如下:
<?xml version="1.0" encoding="utf-8"?><nine-patch xmlns:android="http://schemas.android.com/apk/res/android" android:src="@drawable/red" android:dither="true" />
<?xml version="1.0" encoding="utf-8"?><bitmap xmlns:android="http://schemas.android.com/apk/res/android" android:src="@drawable/red" android:dither="true" />
red 换成你对应的 .9图片即可。
PictureDrawable
RotateDrawable
RotateDrawable 是对一个Drawable进行旋转操作,可以根据level属性控制这个drawable旋转角度,也可以设置相对于它所在容器的对齐方式。
在xml文件中使用rotate作为根节点来定义RotateDrawable.
创建RotateDrawable的代码如下:
<?xml version="1.0" encoding="utf-8"?><rotate xmlns:android="http://schemas.android.com/apk/res/android" android:drawable="@drawable/ic_launcher" android:fromDegrees="0" android:pivotX="50%" android:pivotY="50%" android:toDegrees="180" />
将它引用到ImageView里,发现图片根本没有转变。其实,要让它可以旋转,还需要设置level值。level取值范围为0~10000,应用到rotate,则与fromDegrees~toDegrees相对应,如上面例子的角度范围为0~180,那么,level取值0时,则旋转为0度;level为10000时,则旋转180度;level为5000时,则旋转90度。因为level默认值为0,所以图片没有转变。那么,我们想转180度,其实可以将fromDegrees设为180,而不设置toDegrees,这样,不用再在代码里设置level图片就可以旋转180了。
ScaleDrawable
ScaleDrawable是对一个Drawable进行缩放操作,可以根据level属性控制这个drawable的缩放比率,也可以设置它在容器中的对齐方式。
在xml文件中使用scale作为根节点来创建ScaleDrawable。
创建ScaleDrawable的代码如下:
<?xml version="1.0" encoding="utf-8"?><!-- android:scaleGravity=""可以设置缩放的对齐方式 --><scale xmlns:android="http://schemas.android.com/apk/res/android" android:drawable="@drawable/ic_launcher" android:scaleGravity="left" android:scaleHeight="50%" android:scaleWidth="50%" android:useIntrinsicSizeAsMinimum="false" />
public class ScaleDrawableActivity extends Activity { private ImageView iv; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_scale); iv = (ImageView) findViewById(R.id.iv); iv.getDrawable().setLevel(5000); }}
ShapeDrawable
ShapeDrawable 用于定义一个基本的几何图形(如矩形、圆形、线条等),定义ShapeDrawable的XML文件 的根节点是 shape 元素。
创建ShapeDrawable的代码如下:
<?xml version="1.0" encoding="utf-8"?><shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle"> <!-- 设置填充颜色 --> <solid android:color="#2222" /> <!-- 设置四周的内边距 --> <padding android:bottom="7dp" android:left="7dp" android:right="7dp" android:top="7dp" /> <!-- 设置边框 --> <stroke android:width="3dip" android:color="#ff0" /></shape>
<?xml version="1.0" encoding="utf-8"?><shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle"> <!-- 定义填充渐变颜色 --> <gradient android:angle="45" android:endColor="#80FF00FF" android:startColor="#FFFF0000" /><!-- 设置内填充 --> <padding android:bottom="7dp" android:left="7dp" android:right="7dp" android:top="7dp" /> <!-- 设置圆角矩形 --> <corners android:radius="20dp" /></shape>
<?xml version="1.0" encoding="utf-8"?><shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="oval"> <!-- 定义填充渐变颜色 --> <gradient android:angle="45" android:endColor="#00f" android:startColor="#ff0" android:type="sweep" /> <!-- 设置内填充 --> <padding android:bottom="7dp" android:left="7dp" android:right="7dp" android:top="7dp" /> <!-- 设置圆角矩形 --> <corners android:radius="8dp" /></shape>
PaintDrawable
PaintDrawable无法通过xml创建,只能在Java代码中创建。PaintDrawable 是比较简单的 Drawable了,看过 sdk 文档的朋友知道它只有那么几个方法,这里我就写个简单的 UI 背景。
public class PaintDrawableActivity extends Activity { private ImageView iv; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_paint); iv = (ImageView) findViewById(R.id.iv); PaintDrawable paint = new PaintDrawable(Color.BLUE); paint.setCornerRadii(new float[]{100,200, 100,200, 200,400, 200,400}); iv.setBackground(paint); }}
好了,所有的 Drawable 到此就全部讲完了,但这只是基础的应用,给大家系统的认识一下这些,如果认为知道这个 Drawable 是什么就代表学会了,那是大错特错的。我这个博客只是大致的介绍了一遍它们而已,关于如何去设计 Drawable 还要大家多多练习。
结束语:本文仅用来学习记录,参考查阅。
- Android--各种Drawable介绍
- 一句话介绍Android的各种Drawable
- Android的各种Drawable
- Android中的各种Drawable
- android Drawable setbounds()介绍
- android Drawable setbounds()介绍
- Android Drawable介绍
- Android--Drawable标签介绍
- android Drawable setbounds()介绍
- Android的各种Drawable讲解
- android Drawable各种类型使用
- Android Drawable各种定义方式
- Android的各种Drawable讲解
- Android的各种Drawable讲解
- Android的各种Drawable讲解
- Android的各种Drawable讲解
- Android的各种Drawable详解
- Android的各种Drawable讲解
- 如何去硅谷就业?
- 回溯法解决N皇后问题(java实现)
- 时间与延时
- toj-3515-middle number(优先队列)
- NYOJ 1274 信道安全 裸的最短路 spfa 邻接表 第九届省赛C
- Android--各种Drawable介绍
- hdu 4725 The Shortest Path in Nya Graph(最短路)
- LeetCode ( Combination Sum II)
- farmework 3.5 sp1安装失败
- 关于Array
- opencv 实战,钢板焊接点寻找3
- 关于使用eclipse maven UpdateProject时报错
- [Android](Problem)-"Waiting for target device to come online".
- Dll