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方法。

 

    

posted on 2017-04-05 20:13  AndroidLu  阅读(273)  评论(0)    收藏  举报

导航