Android的Drawable
一、概述
Drawable表示一种可以再Canvas上进行绘制的抽象的概念,Drawable种类有很多,都表示一种图像的概念,但他们并不全是图片,通过颜色也可以构造出不同的图像效果。在实际应用中通常有两种应用,一是用于View的背景,这也是最常用的应用场景,二是ImageView的显示图片。
Drawable存在一内部宽高的概念,通过getIntrinsicWidth和getIntrinsicHeight方法获得,但它们并不代表Drawable的实际大小,在通常情况下,Drawable的大小将随着View大小而改变,固其大部分时候是没有宽高的概念。对于图片构成的Drawable属性即为图片的尺寸,对于由颜色组成的Drawable则不存在高宽的概念。
二、Drawable的分类
1、BitmapDrawable
表示一张图片,可通过方法直接构造也可通过xml的方式定义。常用的属性有:
1、src :即图片资源id
2、antialias:是否开启抗锯齿,一般打开
3、dither:是否开启抖动效果,使其在低质量的屏有较好的显示效果,一般打开
4、filter:是否开启过滤,当图片被拉伸或缩小时保持较好的显示效果,一般打开
5、gravity:对图片定位,除了基本的方位外,还有以下特殊值
1、fill_vertical 垂直方向填充
2、fill_horizontal 水平方向填充
3、fill 填充,默认值
4、clip_vertical 、clip_horizontal 较小使用
6、mipMap:纹理映射,不常用
7、tileMode:平铺模式,即填充画面,此时gravity属性会被忽略,常用的值有
1、repeat 普通填充
2、mirror 镜面投射填充,垂直方向上的图片镜面颠倒
3、clamp 图片四周像素扩展到周围区域
4、disabled
2、NinPatchDrawable
即.9图,根据所需宽高进行相应的缩放并保证不失真,可以在BitmapDrawable中引用.9图。
3、ShapeDrawable
通过颜色构造图形,即可以为填充颜色图形,也可以实现渐变效果。常用属性有
1、shape:指定形状,可选的有rectangle、ring、line、oval,其中line和ring必须与stroke属性结合使用。对于ring有5个特殊的属性:
innerRadius 圆环内半径、thickness 圆环厚度、innerRadiusRatio 圆环内半径占宽度的比例、thicknessRatio 圆环厚度占宽度的比例、userLevel 一般为false,除非作为LevelListDrawable使用
2、corners:四个角的角度,只适用于rectangle。子属性:radius 设置所有角、topRightRadius 右上角角度、其余类似。
3、gradient:渐变效果,子属性有:
angle 渐变的角度,必须为45的倍数,0为从左到右,90为从上到下、centerX 渐变中心横坐标、centerY 渐变中心纵坐标、staerColor 渐变起始色、centeColor 渐变中心色、endColor 渐变结束色、gradientRadius 渐变角度,type= radial时有效、userLevel 一般为false,当作为 StateDrawable时为true、type 渐变类型 有linear、radial、sweep三种,默认为线性。
4、solid:纯色填充 color指定填充颜色
5、stroke:Shape的描边,width、color、dashWidth 虚线宽、dashGap 虚线间隔。
6、padding:表示空白,指包含它的View的空白,有四个方位子属性。
7、size:设置固有宽高 width和height。
4、LayerDrawable
一个Drawable的集合,通过将不同的Drawable放置在不同层实现叠加的效果。对应xml标签<layer-list>,子标签item用于指定多个Drawable,用属性top、right、left、bottom指定相对于View的偏移量。下面的item将覆盖上面的item实现叠加效果。
5、StateListDrawable
根据View的状态切换显示的Drawable,对应标签<selector>,最常见应用场景为Button,实现按压和释放的动态效果。常用的属性有
1、contantSize 为ture时Drawable的固有大小为内部Drawable的最大值,false时,随着状态的改变而改变,默认为false。
2、dither 同上,默认开启
3、variblePadding padding是否随状态的变化而变化,不建议开启
子标签<item>用于指定Drawable,不同item中对应着不同的View状态,常见有:state_pressed 按下状态、state_focused 获得焦点、state_selected 选择状态、state_checked 选中状态,一般用于CheckBox、state_enabled 可用状态。
系统将由上至下选择响应的item,在末尾应添加一未指定状态的item,作为默认选择。
6、LevelListDrawable
根据当前等级设置显示的Drawable,与StateListDrawable类似,这里item指定的是等级范围(minLevel和maxLevel)。通过View的setLevel方法和ImageView的setImageLevel方法设置等级由此改变显示的Drawable。等级范围为0~10000。
7、TransitionDrawable
实现两个Drawable的淡入淡出效果,对应<transition>标签,同样可指定偏移量。子标签<item>指定Drawable,通过Transition的startTransition和reversTransition方法实现淡入淡出及逆过程。
8、InsetDrawable
内嵌其他的Drawable并且四周留下间距。通过insetTop等方法指定内凹大小。
9、ScaleDrawable
根据等级缩放Drawable,对应<scale>标签,常用属性 scaleGravity 与gravity相同,scaleHeight、scaleWidth指定缩放比例,drawable指定drawable。
最终的缩放比例由Level和scaleWidth和scaleHeight共同决定,Level范围为0~10000,最大值时不缩放。
10、ClipDrawable
根据当前等级(level)来裁剪另一个Drawable,同样由drawable指定drawable,clipOrientation 表示裁剪方向,有horizontal和vertical两种值、gravity比较复杂,必须与clipOrientation结合使用。

而Level则指代保留的比例,范围为1~10000,如8000即裁剪掉20%。
三、自定义Drawable
一般情况下由于在xml中无法引用自定义Drawable,所以一般没有必要去自定义Drawable。简单的自定义代码如下
public class CoustomDrawable extends Drawable { private Paint mPaint ; public CoustomDrawable(int color){ mPaint = new Paint(Paint.ANTI_ALIAS_FLAG); mPaint.setColor(color); } @Override public void draw(Canvas canvas) { final Rect r = getBounds(); float cx = r.exactCenterX(); float cy = r.exactCenterY(); canvas.drawCircle(cx,cy,Math.min(cx,cy),mPaint); } @Override public void setAlpha(int alpha) { mPaint.setAlpha(alpha); invalidateSelf(); } @Override public void setColorFilter(ColorFilter colorFilter) { mPaint.setColorFilter(colorFilter); invalidateSelf(); } @Override public int getOpacity() { return PixelFormat.TRANSLUCENT; } }
当自定义Drawable有固有大小时,一般复写getIntrinsicWidth和getInstrinsicHeight方法,因为两者的值会影响View的wrap_content布局。无大小时值为-1。获取Drawable实际区域大小使用getBounds方法。
浙公网安备 33010602011771号