Android的Drawable

Drawable表示的是一种可以在Canvas上进行绘制的抽象概念,他的种类很多,都表示一种图像的概念,但又不全是图片,通过颜色也可以构造出各式各样的图像效果。在实际开发中,Drawable常被用来作为View的背景使用。Drawable一般都是通过xml来定义的,也可以通过代码来进行创建具体的Drawable对象,只不过代码创建会稍显复杂。在Android的设计中,Drawable是一个抽象类,它是所有Drawable对象的基类,每一个具体的Drawable都是他的子类,比如BitmapDrawable,ShapDrawable等。
Drawable的内部宽高这个参数比较重要,通过getIntrinsicWidth和getIntrinsicHeight获取,但并不是所有的Drawable都有内部宽高,比如一张图片所形成的Drawable,他的内部宽高就是图片的宽高,但是一个颜色所形成的Drawable他就没有内部宽高的概念。另外需要注意的是,Drawable的内部宽高不等同于它的大小,一般来说Drawable是没有大小概念的,当用作View的背景时,Drawable会被拉伸至View的同等大小。下面简单介绍集中常见的Drawable的使用:
1、BitmapDrawable
他表示的就是一张图片,实际开发中,我们可以直接引用原始的图片即可,可以通过xml来表述它,可以设置更多的效果。如下:

<?xml version="1.0" encoding="utf-8"?>
<bitmap xmlns:android="http://schemas.android.com/apk/res/android"
    android:src="@drawable/image"
    android:antialias="true|false"
    android:dither="true|false"
    android:filter="true|false"
   android:gravity="top|left|bottom|right|center|center_horizontal|center_vertical|fill|fill_horizontal|fill_vertical|clip_vertical|clip_horizontal"
    android:mipMap="true|false"
    android:tileMode="disable|repeat|mirror|clamp">
</bitmap>

各不同属性的含义:
android:src
表示图片资源的id
android:antialias
表示是否开启抗锯齿功能。开启后图片会变得平滑,同时也会在一定程度上降低图片的清晰度,但这个降低的幅度可以忽略不计,因此应该开启。
android:dither
表示是否开启抖动效果。当图片的像素配置和手机屏幕的像素配置不一致时,开启这个选项可以让高质量的图片在低质量的手机上还能保持较好的显示效果,因此这个选项应该开启。
android:filter
是否开启过滤效果。当图片的尺寸被拉伸或压缩时,开启过滤效果可以保持较好的显示效果,因此这个选项也应该开启。
android:gravity
当图片小于容器的尺寸时,设置此选项可以对图片进行定位。这个属性的可选项比较多,不同的选项可以通过“|”来组合使用。默认值使fill
top|bottom|left|right 将图片放在容器的顶部|底部|左部|右部,不改变图片的大小
center_vertical|center_horizontal|center 使图片竖直|水平|竖直和水平同时居中,不改变图片的大小
fill_vertical|fill_horizontal|fill 使图片竖直方向|水平方向|竖直和水平方向 填充容器
clip_vertical|clip_horizontal 竖直|水平方向的剪裁
android:mipMap
这是一种图像相关的处理技术,也叫纹理映射,在平时开发中不常用,默认值叫false。
android:tileMode
平铺模式。这个选项有如下几个值:disabled|repeat|mirror|clamp
disabled表示关闭平铺模式,这也是默认值。当开启平铺模式时,gravity属性会被忽略。
repeat 表示简单的水平和竖直方向上的平铺效果。
mirror 表示一种在水平和竖直方向上的镜面投影效果。
clamp 表示图片四周的像素会扩展到周围区域。
2、NinePatchDrawable
它表示的是一张.9格式的图片,.9格式的图片可以自动地根据所需的宽高进行相应的缩放并保证不失真,它和BitmapDrawable一样,都表示一张图片,在实际使用中,直接引用一张图片就可以了。

<?xml version="1.0" encoding="utf-8"?>
<nine-patch xmlns:android="http://schemas.android.com/apk/res/android"
    android:src="@drawable/image"
    android:dither="true">

</nine-patch>

3、ShapDrawable
一种常见的Drawable,可以理解为通过颜色来构造图形,可以是纯色的图形,也可以是具有渐变效果的图形。

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
    android:shape="rectangle">

    <corners android:radius="5px"
        android:topLeftRadius="5px"
        android:topRightRadius="5px"
        android:bottomLeftRadius="5px"
        android:bottomRightRadius="5px"/>

    <gradient android:angle="90"
        android:centerX="10"
        android:centerY="10"
        android:startColor="#ff0000"
        android:centerColor="#00ff00"
        android:endColor="#0000ff"
        android:gradientRadius="5dp"
        android:type="linear"
        android:useLevel="true"/>

    <padding android:left="5dp"
        android:right="5dp"
        android:top="5dp"
        android:bottom="5dp"/>

    <size android:width="100dp"
        android:height="100dp"
        />

    <solid android:color="@color/colorPrimary"/>

    <stroke android:width="1dp"
        android:color="@color/colorAccent"
        android:dashWidth="1dp"
        android:dashGap="2dp"/>

</shape>

通过Shape标签创建的Drawable,其实体类实际上是GradientDrawable。
android:shape
图形的形状。rectangle(矩形),oval(椭圆),line(横线),ring(圆环),默认值是rectangle。另外line和ring这两个选项必须要通过stoke标签来指定线的宽度和颜色等信息,否则达不到预期的效果。
针对ring这个形状还有5个特殊的属性:
android:innerRadius 圆环的内半径,和android:innerRadiusRatio同时存在时,以android:innerRadius为准
android:thickness 圆环的厚度,即外半径减去内半径的大小,和android:thicknessRatio同时存在时,以android:thick为准。
android:innerRadiusRatio 内半径占整个Drawable宽度的比例,默认为9,如果为n,内半径 = 宽度/n
android:thicknessRatio 厚度占整个Drawable宽度的比例,默认值为3,如果为n,厚度 = 宽度/n
android:useLevel 一般都应该为false,否则有可能无法达到预期的效果,除非他被用来当作LevelListDrawable来使用。
corners标签
表示shape的四个角的角度。他只适用于矩形shape,这里的角度是指圆角的角度,用px表示。
android:radius 为四个角同时设定相同的角度,优先级较低,会被其他四个属性覆盖。
android:topLeftRadius 设定最上角的角度。
android:topRightRadius 设定右上角的角度
android:bottomLeftRadius 设定左下角的角度
android:bottomRightRadius 设定右下角的角度
gradient标签
它和solid标签互斥。
android:angle 渐变的角度,默认0,值必须为45的倍数,0表示从左到右,90表示从下到上。
android:centerX 渐变的中心横坐标
android:centerY 渐变的中心纵坐标
android:startColor 渐变的起始色
android:centerColor 渐变的中间色
android:endColor 渐变的结束色
android:gradientRadius 渐变半径,当type = radial时有效
android:type 渐变类别 linear(线性渐变)radial(径向渐变)sweep(扫描线渐变)
android:useLevel 一般为false,当Drawable为StateListDrawable时使用true
solid标签
这个标签表示纯色填充,通过android:color即可指定shape中填充的颜色。
stroke标签
Shape的描边。
android:width 描边的宽度
android:color 描边的颜色
android:dashWidth 组成虚线的线段的宽度
android:dashGap 组成虚线的线段之间的间隔
padding标签
他表示空白,但他不是表示shape的空白,而是包含它的View的空白。
size标签
shape的大小,这个表示的是shape的固有大小,但他一般来说并不是shape的最终显示大小。
4、LayerDrawable
表示一种层次化的Drawable集合,通过将不同的Drawable放置在不同的层上面从而达到一种叠加后的效果。

<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:drawable="@drawable/image"
        android:id="@+id/drawable1"
        android:top="5px"
        android:bottom="5px"
        android:left="5px"
        android:right="5px"/>
</layer-list>

一个layer-list中可以包含多个item,每个item表示一个Drawable,item中可以直接引用一个drawable,也可以在item中自定义一个Drawable。
5、StateListDrawable
对应于selector标签,它也是表示Drawable集合,每个Drawable都对应着View的一种状态,这样系统就会根据View的状态来选择合适的Drawable。

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android"
    android:constantSize="true"
    android:dither="true"
    android:variablePadding="false">

    <item android:drawable="@drawable/image"
        android:state_focused="true"/>

</selector>

android:constantSize
表示StateListDrawable的固有大小是否不随着状态的改变而改变。因为状态的改变会导致StateListDrawable切换到具体的Drawable,而不同的Drawable具有不同的固有大小,True表示StateListDrawable的固有大小保持不变,这时他的固有大小是内部所有Drawable的固有大小最大值,false则会随着状态的改变而改变。
android:dither
是否开启抖动效果。开启此选项可以让图片在低质量的屏幕上仍然显示较好的效果。
android:variablePadding
表示StateListDrawable的padding是否随着状态的改变而改变。true表示会随着状态的改变而改变,false则表示StateListDrawable的padding是内部所有Drawable的padding的最大值。默认为false,且不建议开启。
item标签表示一个具体的Drawable,android:drawable 是一个已有的drawable资源id,剩下的属性表示View的各种状态。
android:state_pressed 表示按下状态
android:state_focused 表示View已经获取了焦点
android:state_selected 表示用户选择了View
android:state_checked 表示用户选中了View,一般适用于CheckBox 这类在选中和非选中之间进行切换的View
android:state_enabled 表示View当前可用状态
系统会根据View当前状态从selector中选择对应的item,按照从上到下的顺序查找,直到查找到第一条匹配的item。一般来说默认的item都应该放在selector的最后一条并且不附带任何状态,这样当上面的item都无法匹配View的当前状态时,系统就会选择默认的item,因为默认的item不附带状态,所以它可以匹配View的任何状态。
6、LevelListDrawable
它同样表示一个Drawable集合,集合中的每个Drawable都有一个等级的概念,根据不同的等级,LevelListDrawable会切换对应的Drawable。

<?xml version="1.0" encoding="utf-8"?>
<level-list xmlns:android="http://schemas.android.com/apk/res/android">

    <item android:drawable="@drawable/image"
        android:maxLevel="1"
        android:minLevel="0"/>
</level-list>

上述语法中,每一个item表示一个Drawable,并有对应的等级范围。由android:maxLevel和android:minLevel来指定,在最小值和最大值之间的等级会对应此item中的Drawable。当他作为View的背景时,可以通过Drawable的setLevel方法来设置不同的等级从而切换具体的Drawable。Drawable的等级范围是0~10000.
7、TransitionDrawable
它用于实现两个Drawable之间的淡入淡出的效果。

<?xml version="1.0" encoding="utf-8"?>
<transition xmlns:android="http://schemas.android.com/apk/res/android">

    <item android:drawable="@drawable/image"/>
    <item android:drawable="@drawable/ic_launcher"/>
    
</transition>

然后将上述TransitionDrawable设置为Textview的背景

 <TextView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:id="@+id/tvTransition"
        android:background="@drawable/transition_drawable"/>

然后通过startTransition和reverseTransition方法来实现淡入淡出。

        TextView textView = (TextView) findViewById(R.id.tvTransition);
        TransitionDrawable drawable = (TransitionDrawable) textView.getBackground();
        drawable.startTransition(1000);
//drawable.reverseTransition(1000);

8、InsetDrawable
它可以将其他的Drawable内嵌到自己当中,并可以在四周留出一定的间距。当一个View希望自己的背景比自己的实际区域小时,可以采用InsetDrawble来实现。

<?xml version="1.0" encoding="utf-8"?>
<inset xmlns:android="http://schemas.android.com/apk/res/android"
    android:drawable="@drawable/image"
    android:insetTop="5dp"
    android:insetRight="5dp"
    android:insetLeft="5dp"
    android:insetBottom="5dp">

</inset>

9、ScaleDrawable
他可以根据自己的等级将指定的Drawable缩放到一定比例。

<?xml version="1.0" encoding="utf-8"?>
<scale xmlns:android="http://schemas.android.com/apk/res/android"
    android:drawable="@drawable/image"
    android:scaleGravity="center"
    android:scaleWidth="70%"
    android:scaleHeight="70%"
    >
</scale>

直接使用上面的Drawable资源是不行的,还需要设置ScaleDrawable的等级不等于0.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值