Android的Drawable

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使用标签,可以将指定的Drawable内嵌到自己当中,特殊的是它可以设置四周的间距,作为背景时,设定值为背景与view边框的距离,用layerList同样可以实现。

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使用标签,它可以对指定的drawable进行缩放。它的scaleGravity属性作用同BItmap一样。另外还有两个特殊属性,scaleHeight和scaleWidt指定宽和高的缩放比例,接收百分比数值。需要注意的是,ScaleDrawable缩放效果不仅仅受scaleHeight和scaleWidth影响,还要指定Level。默认的Level为0,这时候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

示例代码:


你可能感兴趣的:(Android的Drawable)