Drawable简介
提到Drawable,第一反应肯定是存放图片的位置,实际上,Drawable并不仅仅指图片。它可以理解为一种图片的概念,比如颜色填充,也可以理解为一种图片。
Drawable类是一个抽象类,它有BitmapDrawable,ShapeDrawable,LayerDrawable,StateListDrawable等常用子类。
BitmapDrawable
BitmapDrawable就是一张图片,通过src属性定义指向的图片资源,然后对该图片进行相关设置主要属性如下:
//使用代码进行动态设置:
Bitmap bitmap = BitmapFactory.decodeResource(getResources(),R.drawable.ic_launcher);
BitmapDrawable bitmapDrawable = new BitmapDrawable(bitmap);
bitmapDrawable.setTileModeXY(Shader.TileMode.CLAMP, Shader.TileMode.CLAMP);
bitmapDrawable.setAntiAlias(true);
bitmapDrawable.setDither(true);
除了针对常见图片的BitmapDrawable之外,NinePatchDrawable对应的是.9图片,用法同BitmapDrawable一样,根标签是nine-patch
ColorDrawable
ColorDrawable用纯色填充一块区域,使用也最简单,只有一个属性,color:
//代码设定:
ColorDrawable colorDrawable = new ColorDrawable(0xffff0000);
//使用颜色:
mImageView.setBackground(new ColorDrawable(0xffff0000));
mImageView.setBackgroundColor(Color.argb(255,00,255,00));
Android中对颜色的设定采用ARGB模式,xml中可以不指定alpha值,但是在代码中使用十六进制数值设置颜色时,必须制定alpha值,否则默认为0x00,全透明,是看不到颜色的。
GradientDrawable(ShapeDrawable)
GradientDrawable表示一个渐变区域,可以实现线性渐变、发散渐变、和平铺渐变。它的主要属性如下:
//设置Shape形状,rectangle(矩形),oval(椭圆),line(直线),ring(圆形)四个可选值
//一般为false,只有当Drawable作为StateListDrawable使用才设置true
//线条间距
LayerDrawable
LayerDrawable包含多个item,每个item表示一个drawable,LayerDrawable将所包含的item放置在不同的层次上,第一个item在最底层,依次向上叠加:
-
-
item子节点可以直接定义一个Drawable,也可以使用android:drawable属性来引用一个Drawable,layer-list没有属性节点,只包含Item子节点。Item节点属性除了android:drawable,还有android:top/left/right/bottom用来设定各个方向的偏移距离
StateListDrawable
StatelistDrawable也是一个Drawable集合,每个Drawable对应View的一种状态,只要用在设置View的背景。它使用selector标签:
//当前窗口是否获取焦点。比如弹出对话框就会失去焦点
系统会根据View的当前状态从selector中选择对应的item,选择的时候会从上向下一直找到第一条匹配的item,通常会设置一个默认的item放在最后,不设置任何的状态。这样当系统在上边的item中找不到对应的状态时,就会选择最后一个默认的item,它不附带任何状态,可以匹配给所以状态。
//在控件中使用Drawable
LevelListDrawable
LevelListDrawable也是一系列Drawable集合,它通过Level来匹配item。
item子节点除了指定Drawable之外,只有两个属性android:maxLevel指定最高Level(10000),android:minLevel指定最低Level(0),在这两个值中间就会匹配该item。匹配的时候也是从上向下,直到匹配到一条合适的item 。所以,通常只需要指定maxLevel就可以了,将item按maxLevel从小到大依次排列下来。
Level的设置使用Drawable的setLevel方法来设定。如果是作为ImageView的前景,也可以通过ImageView的setImageLevel来设定。
TransitionDrawable
transition其实是继承自layer-list的,只是,transition只能管理两层drawable,另外提供了两层drawable之间切换的方法,切换时还会有淡入淡出的动画效果。示例代码如下:
然后在控件中指定背景:
transition标签生成的Drawable对应的类为TransitionDrawable,要切换时,需要主动调用TransitionDrawable的startTransition()方法,参数为动画的毫秒数,也可以调用reverseTransition()方法逆向切换。
Button mButton = (Button) findViewById(R.id.btn1);
TransitionDrawable transitionDrawable = mButton.getBackground();
transitionDrawable.startTransition(500); //正向切换,即从第一个drawable切换到第二个
transitionDrawable.reverseTransition(500); //逆向切换,即从第二个drawable切换回第一个
InsetDrawable
InsetDrawable使用
android:drawable 指定drawable资源,如果不设置该属性,也可以定义drawable类型的子标签
android:visible 设置初始的可见性状态,默认为false
android:insetLeft 左边距
android:insetRight 右边距
android:insetTop 顶部边距
android:insetBottom 底部边距
android:inset 设置统一边距,会覆盖上面四个属性,但API Level要求为21,即Android 5.0
ScaleDrawable
ScaleDrawable使用
//API 24以上才支持
//在控件中使用:这时候是看不到图片的,没有设置Level,图片不会绘制出来
//设置Level:
mScaleImageView.setImageLevel(1);
注意的是,Level对缩放比例的影响,Level值越大,Drawable就越大,如果设置为10000(Level最大值),那么不管缩放比例设置多少,都不会进行缩放。而scaleHeight和scaleWidth相反,值越大,Drawable越小。
ClipDrawable
ClipDrawable用来对Drawable进行裁剪,它也是根据Level来决定裁剪范围,10000表示不裁剪,0表示全部裁剪,就看不到了。裁剪的方向通过clipOritation来设置vertical和horizontal,除此之外还有一个Gravity属性,它和clipOritation一起决定了裁剪方式。
Gravity有以下取值:
top: Drawable放在容器顶部,竖直裁剪的时候从底部开始
bottom:Drawable放在容器底部,竖直裁剪时从顶部开始
left:默认值。Drawable放在容器左边,水平裁剪时从右边开始
right:放在右边,水平裁剪从左边开始
center_vertical:Drawable竖直居中,不改变大小,竖直裁剪从上下同时开始
fill_vertical:竖直方向填充容器。竖直裁剪的时候,只有clipDrawable的level为0,才有裁剪行为
center_horizontal:水平居中,不改变大小,水平裁剪从左右同时开始
fill_horizontal:水平填充,水平裁剪只有当clipDrawable的level为0,才有裁剪行为
center:水平和垂直居中,竖直方向上下,水平方向左右同时裁剪
fill:水平和竖直方向填充容器,只有当clipDrawable的level为0,才有裁剪行为
其他标签
-
rotate
标签用来控制Drawable的旋转,主要用以下属性: android:drawable 指定drawable资源,如果不设置该属性,也可以定义drawable类型的子标签
android:fromDegrees 起始的角度度数
android:toDegrees 结束的角度度数,正数表示顺时针,负数表示逆时针
android:pivotX 旋转中心的X坐标,浮点数或是百分比。浮点数表示相对于drawable的左边缘距离单位为px,如5; 百分比表示相对于drawable的左边缘距离按百分比计算,如5%; 另一种百分比表示相对于父容器的左边缘,如5%p; 一般设置为50%表示在drawable中心
android:pivotY 旋转中心的Y坐标
android:visible 设置初始的可见性状态,默认为false将一张图片旋转180度代码如下:
rotate同样与Level有关。Level值从0-10000分别对应fromDegrees和toDegrees,比如Level设置5000就会旋转90度。因为level值默认为0,所以默认是不会旋转的,如果要旋转的话可以将android:fromDegrees直接设置180度,开始的状态就已经完成旋转了。
- animation-list
用来将一系列drawable构建成帧动画。通过添加item子标签设置每一帧使用的drawable资源,以及每一帧持续的时间。示例代码如下:
android:oneshot属性设置是否循环播放,设为true时,只播放一轮就结束,设为false时,则会轮询播放。
android:duration属性设置该帧持续的时间,以毫秒数为单位。
animation-list对应的Drawable类为AnimationDrawable,要让动画运行起来,需要主动调用AnimationDrawable的start()方法。另外,如果在Activity的onCreate()方法里直接调用start()方法会没有效果,因为view还没有初始化完成是播放不了动画的。
-
animation-rotate
rotate标签只是将原有的drawable转个角度变成另一个drawable,它是静态的。而animated-rotate则会让drawable不停地做旋转动画。
animated-rotate可设置的属性只有四个:
android:drawable 指定drawable资源,如果不设置该属性,也可以定义drawable类型的子标签
android:pivotX 旋转中心的X坐标
android:pivotY 旋转中心的Y坐标
android:visible 设置初始的可见性状态,默认为false
示例代码: