神奇的Drawable文件夹---背景图篇

作者: 食梦兽 | 来源:发表于2016-08-28 17:28 被阅读1765次

    Android开发中,和布局文件对应 View 一样,Drawable 文件也对应着一个类--Drawable。
    如下面两个表所示。

    节点 View 类 类型
    LinearLayout android.widget.LinearLayout ViewGroup
    TextView android.widget.TextView View
    Button android.widget.Button View
    ... ... ...

    假设在布局文件的根布局使用了 LinearLayout , 里面包含了一个 TextView 和 一个 Button,随后在 Activity 中使用 setContentView(R.layout.main); 或者使用 LayoutInflater.from(mContext).inflate(R.id.main, null, false); 来加载 view,Android 会把布局文件中的每个节点都转换对应的类,组合成一个新的 view,用在 Activity 背景上或者得到这个 view做其他的操作。

    下面来看今天的主题---Drawable,以布局文件来类比。

    序号 节点 Drawable 具体子类 说明
    1 [bitmap] BitmapDrawable 对bitmap的封装
    2 [color] ColorDrawable 把颜色封装成可以显示的Drawable
    3 [shape] ShapeDrawable 绘制基础的形状图形,最常用的Drawable之一,可用于定义圆角、渐变色、圆环等效果
    4 [selector] StateListDrawable 表示一组有状态的图像的集合,可用于给button等设置点击和正常状态下的图片
    5 [level-list] LevelListDrawable 表示一组有等级的图像的集合
    6 [layer-list] LayerDrawable 表示图层
    7 [nine-patch] NinePatchDrawable 对.9.png的封装
    8 [clip] ClipDrawable 对drawable裁剪
    9 [inset] InsetDrawable 用距离边框的距离表示drawable大小
    10 [ripple] RippleDrawable 波纹点击效果,API21以上

    下面看怎样在xml文件中使用这些 Drawable,当然和布局文件中的 view 一样,我们也可以使用java代码来创建这些对象,但是我们一般不这样做,就像我们不会用java代码创建一个复杂的布局一样。

    一、BitmapDrawable

    在 drawable 文件夹下创建一个xml文件,修改 <selector/> 根节点为 <bitmap/>,并且增加 src 属性,像下面这样:

    <?xml version="1.0" encoding="utf-8"?>
    <bitmap xmlns:android="http://schemas.android.com/apk/res/android"
        android:src="@drawable/ic_launcher">
    </bitmap>
    

    这样,我们就可以在文件文件中设置 view 的背景 android:background="@drawable/bitmap",bitmap 就这么简单,我们一般也不会这样来用,使用的话也是配合别的 Drawable,用于包装图片资源,比如在 StateListDrawable(selector节点)下,对应每一个drawable 设置不同的 BitmapDrawable。

    bitmap 节点下不能再包含节点。
    所有的设置都通过属性来完成。

    下表列出所有的属性供参考。

    属性 参数类型 说明
    android:src Drawable resource 显示的图片,不能为color等,只能为图片资源
    android:alpha float 透明度0-1,值越小,越透明
    android:antialias boolean 是否开启抗锯齿
    android:autoMirrored boolean 设置图片是否需要镜像反转,当布局方向是RTL,即从右到左布局时才有用,API19以上
    android:dither boolean 是否抖动
    android:filter boolean 设置是否允许对图片进行滤波
    android:gravity center... 图片对其方式,同布局文件中view的gravity属性
    android:mipMap boolean 设置是否可以使用mipmap API18以上
    android:tileMode disabled、mirror、clamp、repeat X、Y轴平铺方式, disabled(默认):不使用平铺;mirror:镜面;clamp:复制图片边缘的颜色来填充容器剩下的空白部分;repeat:图片重复铺满
    android:tileModeX 同上 X轴平铺方式,参数意义同上
    android:tileModeY 同上 Y轴平铺方式,参数意义同上
    android:tint color 给图片着色
    android:tintMode add、multiply、screen、src_atop、src_in、src_over 着色模式

    二、ColorDrawable

    ColorDrawable 对应xml文件中的 <color/> 节点,同样在 drawable 文件夹下新建一个xml文件,内容如下:

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

    color 节点只有唯一一个也是必须的属性,android:color 使用color资源文件中的color赋值即可。同样没有子节点,最为简单的一个Drawable,把color 值转化为了Drawable对象,以便在其他需要Drawable的地方使用。

    三、ShapeDrawable

    使用 <shape/> 节点用来定义形状,可以定义矩形、椭圆、线、圆环四种类型的形状。shape 节点包含一些属性和子节点:

    属性:

    属性 参数类型 说明
    android:shape rectangle、oval、line、ring 定义形状的类型,rectangle(矩形)、oval(椭圆)、line(线)、ring(圆环)默认为矩形
    android:innerRadius int 圆环内圆的半径
    android:innerRadiusRatio int 内半径占整个Drawable宽度的比例,默认值为9
    android:thickness int 圆环的厚度
    android:thicknessRatio int 厚度占整个Drawable宽度比例,默认值为3
    android:useLevel boolean 设置等级,配合LevelListDrawable使用时设置
    android:visible boolean 设置是否可见
    android:dither boolean 是否抖动
    android:tint color 给图片着色
    android:tintMode add、multiply、screen、src_atop、src_in、src_over 着色模式

    子节点:

    solid 填充色

    表示形状的填充色,只有color一个属性:android:color

    <?xml version="1.0" encoding="utf-8"?>
    <shape xmlns:android="http://schemas.android.com/apk/res/android">
        <solid android:color="@color/colorAccent"/>
    </shape>
    
    填充颜色的矩形

    填充颜色的矩形.png

    <?xml version="1.0" encoding="utf-8"?>
    <shape xmlns:android="http://schemas.android.com/apk/res/android"
           android:shape="oval">
        <solid android:color="@color/colorAccent"/>
    </shape>
    
    填充颜色的椭圆

    填充颜色的椭圆.png

    <?xml version="1.0" encoding="utf-8"?>
    <shape xmlns:android="http://schemas.android.com/apk/res/android"
           android:innerRadius="50dp"
           android:shape="ring"
           android:thickness="10dp"
           android:useLevel="false">
        <solid android:color="@color/colorAccent"/>
    </shape>
    
    填充颜色的圆环

    填充颜色的圆环.png

    <?xml version="1.0" encoding="utf-8"?>
    <shape xmlns:android="http://schemas.android.com/apk/res/android"
           android:shape="line">
        <stroke
            android:width="4dp"
            android:color="@color/colorAccent"
            android:dashGap="8dp"
            android:dashWidth="4dp"/>
    </shape>
    
    线

    线.png

    corners 圆角

    表示圆角的半径,对应有四个角的属性,和一个总体的属性

    属性 参数类型 说明
    android:radius int 统一设置圆角半径
    android:bottomLeftRadius int 设置左下角圆角半径
    android:bottomRightRadius int 设置右下角圆角半径
    android:topLeftRadius int 设置左上角圆角半径
    android:topRightRadius int 设置右上角圆角半径
    <?xml version="1.0" encoding="utf-8"?>
    <shape xmlns:android="http://schemas.android.com/apk/res/android"
           android:shape="rectangle">
        <corners
            android:bottomLeftRadius="3dp"
            android:radius="5dp"/>
        <solid android:color="@color/colorAccent"/>
        <size
            android:width="30dp"
            android:height="30dp"/>
    </shape>
    
    
    圆角

    圆角.png

    gradient 渐变色

    表示渐变色,可以设置形状填充的颜色为渐变色

    属性 参数类型 说明
    android:angle int 设置旋转的角度,45的倍数
    android:startColor color 颜色变化的起始值
    android:endColor color 颜色变化的结束值
    android:centerColor color 中间的颜色
    android:centerX int 渐变中心点的横坐标
    android:centerY int 渐变的中心点的纵坐标
    android:gradientRadius int 渐变的梯度,当android:type=”radial”有效
    android:type linear 、 radial 、 sweep 渐变类别,linear(线性)为默认值,radial(径内渐变),sweep(扫描渐变)
    android:useLevel boolean 设置等级,配合LevelListDrawable使用时设置
    <?xml version="1.0" encoding="utf-8"?>
    <shape xmlns:android="http://schemas.android.com/apk/res/android">
        <gradient
            android:type="sweep"
            android:endColor="@color/colorAccent"
            android:startColor="@color/colorPrimary"/>
        <size
            android:width="30dp"
            android:height="30dp"/>
    </shape>
    
    渐变色

    渐变色.png

    stroke 边框

    表示边框。

    属性 参数类型 说明
    android:color color 边框颜色
    android:width int 边框宽度
    android:dashGap int 边框虚线间隙大小
    android:dashWidth int 边框虚线每个小节的宽度
    <?xml version="1.0" encoding="utf-8"?>
    <shape xmlns:android="http://schemas.android.com/apk/res/android">
        <stroke
            android:width="2dp"
            android:color="@color/colorAccent"
            android:dashGap="2dp" // 和dashWidth一起设置,若不设置则为实线
            android:dashWidth="3dp"/>
        <size
            android:width="30dp"
            android:height="30dp"/>
    </shape>
    
    虚线边框

    虚线边框.png

    size 大小

    设置背景大小,width和height俩属性。一般来说这个值不是shape的最终显示大小,因为shape作为背景时会根据View的大小而填充其背景,因此Shape的大小很多时候是View的大小决定的。

    padding 内边距

    表示内容或子标签边距,4个属性top、bottom、left、right,需要注意的是这个标签的作用是为内容设置与当前应用此shape的View的边距,而不是设置当前View与父元素的边距。

    四、StateListDrawable

    StateListDrawable 对应 drawable 文件夹下的xml文件的 <selector/> 节点,表示drawable集合。selector 可以包含不止一个 item 节点,每个 item 节点对应两类属性,一类只有一个 android:drawable, 另一类是类似于 android:state_pressed,表示当前所在view的状态,有按下、选择、获得焦点等十几种状态,需要注意不是每一个view都有这么多状态。
    最常见的场景是给 Button 设置点击和正常状态下的drawable。

    selector 节点 属性:

    属性 参数类型 说明
    android:autoMirrored boolean 设置图片是否需要镜像反转
    android:constantSize boolean 设置自身大小是否随着其状态改变而改变
    android:enterFadeDuration int 状态改变时,新状态展示时的淡入时间,以毫秒为单位
    android:exitFadeDuration int 状态改变时,新状态消失时的淡入时间,以毫秒为单位
    android:variablePadding boolean padding是否随状态的改变而改变,默认false

    子节点 item 属性:

    属性 参数类型 说明
    android:drawable drawable 对应drawable,可以为color、bitmap、shape等单一drawable
    android:android:state_xxx boolean 设置不同的状态
    <?xml version="1.0" encoding="utf-8"?>
    <selector xmlns:android="http://schemas.android.com/apk/res/android">
        <item android:drawable="@color/button_press"
              android:state_pressed="true"/>
        <item android:drawable="@color/button_norm"
              android:state_pressed="false"/>
    </selector>
    

    子节点 item 还可以包含许多子节点,如bitmap、shape、color、动画相关的等,下面给出两个例子说明用法。

    在布局文件中给view设置 android:background="@drawable/button_seleter" 即可,实现在点击view时显示不同的背景图,有点击的效果反馈。

    这里需要注意一点:
    如果上边所说的view是 Button 的话,直接可以看到效果,但是,实际开发中,我们可能要给 LinearLayout、TextView 设置点击效果,使用上面的方法是没有效果的。

    解决方法:给这个 view 添加点击事件的监听。

    上边代码中的 android:drawable 不只可以设置为color类型的drawable,还可以设置为bitmapDarwable、ShapeDrawable等,下面看一个圆角点击效果的例子。

    <?xml version="1.0" encoding="utf-8"?>
    <selector xmlns:android="http://schemas.android.com/apk/res/android">
        <item android:state_pressed="false">
            <shape>
                <corners android:radius="10dp"/>
                <solid android:color="@color/button_norm"/>
            </shape>
        </item>
        <item android:state_pressed="true">
            <shape>
                <corners android:radius="10dp"/>
                <solid android:color="@color/button_press"/>
            </shape>
        </item>
    </selector>
    

    设置在view上的效果为有圆角效果,并且按下的时候,背景后改变。
    以上代码在 selector 节点下有两个 item 节点,item节点设置了是否点击的状态,并且包含了一个 shape 节点,作为对应状态下的drawable对象。

    五、LevelListDrawable

    LevelListDrawable 对应xml文件中的 <level-list/> 节点,表示一组由等级大小标志的 drawable,不同的等级可以为之设置不同的背景drawable。

    此节点没有参数,只能包含不止一个的 item 子节点。

    item 节点的属性:

    属性 参数类型 说明
    android:drawable drawable 对应drawable,可以为color、bitmap、shape等单一drawable
    android:maxLevel int 设置等级范围的最大值
    android:minLevel int 设置等级范围的最小值
    <?xml version="1.0" encoding="utf-8"?>
    <level-list xmlns:android="http://schemas.android.com/apk/res/android">
        <item
            android:drawable="@color/colorAccent"
            android:maxLevel="10"
            android:minLevel="1"/>
        <item
            android:drawable="@color/colorPrimary"
            android:maxLevel="20"
            android:minLevel="11"/>
    </level-list>
    

    简单起见,使用 ColorDrawable 来设置对应的 android:drawable,有两种不同的背景,对应都有不同的等级范围。
    设置给view 作为背景,像这样:android:background="@drawable/level"

    在java代码中,获取到此view的 background,再设置其level属性的值,就会变为对应等级的背景。

    boolean flag;
    
    public void onClick(View v) {
        if (flag) {
            view.getBackground().setLevel(3);
        } else {
            view.getBackground().setLevel(13);
        }
        this.flag = !this.flag;
    }
    

    六、LayerDrawable

    LayerDrawable 也表示 drawable 集合,对应xml文件中的<layer-list/>节点,根据名称我们可以知道其中的每一个 drawable 都代表一个图层,新加入的 drawable 位于背景图片的最高图层。
    item 的 android:drawable 属性也是可以设置为复杂的drawable的,方便起见,这里使用 colorDrawable。

    属性 参数类型 说明
    android:opacity transparent、translucent、opaque 设置透明度:transparent透明、translucent半透明、opaque不透明
    android:paddingXxx int 设置等级范围的最大值

    子节点 item 属性,都是定位的属性,像height,width,gravity,bottom,top,left,right等。

    <?xml version="1.0" encoding="utf-8"?>
    <layer-list xmlns:android="http://schemas.android.com/apk/res/android">
        <item
            android:bottom="10dp"
            android:drawable="@color/colorAccent"
            android:left="10dp"
            android:right="10dp"
            android:top="10dp"
            />
        <item
            android:bottom="50dp"
            android:drawable="@color/colorPrimary"
            android:left="50dp"
            android:right="50dp"
            android:top="50dp"
            />
    </layer-list>
    

    效果如下:

    LayerDrawable

    七、NinePatchDrawable

    NinePatchDrawable 是点九图的封装,xml文件中对应 <nine-patch/> 标签,属性和BitmapDrawable中属性的含义相同。

    <nine-patch xmlns:android="http://schemas.android.com/apk/res/android"   
        android:src="@drawable/btn_bk"
        android:dither="true"/> 
    

    八、ClipDrawable

    ClipDrawable 代表可以裁剪的drawable,对应xml文件中的<clip/>标签,通过当前设置的比例来裁剪Drawable,ClipDrawable的setLevel()方法可以控制显示比例,ClipDrawable的level值范围在[0,10000],level的值越大裁剪的内容越少,当level为10000时则完全显示,而0表示完全裁剪,不可见。

    <clip/>标签的属性:

    属性 参数类型 说明
    android:drawable drawable 对应drawable,可以为color、bitmap、shape等单一drawable
    android:clipOrientation horizontal、vertical 裁剪的方向,horizontal水平、vertical垂直
    android:gravity right、top等 设置drawable所在位置,配合android:clipOrientation属性一起用

    android:gravity 可以设置下表所示的值:

    属性 描述说明
    top 将这个对象放在容器的顶部,不改变其大小。当clipOrientation 是”vertical”,裁剪从底部开始
    bottom 将这个对象放在容器的底部,不改变其大小。当clipOrientation 是”vertical”,裁剪从顶部开始
    left 将这个对象放在容器的左部,不改变其大小。当clipOrientation 是 “horizontal”,裁剪从drawable的右边(right)开始,默认值
    right 将这个对象放在容器的右部,不改变其大小。当clipOrientation 是 “horizontal”,裁剪从drawable的左边(left)开始
    center 将这个对象放在水平垂直坐标的中间,不改变其大小。当clipOrientation 是 “horizontal”裁剪发生在左右。当clipOrientation是”vertical”,裁剪发生在上下。
    center_vertical 将对象放在垂直中间,不改变其大小,如果clipOrientation 是 “vertical”,那么从上下同时开始裁剪
    center_horizontal 将对象放在水平中间,不改变其大小,clipOrientation 是 “horizontal”,那么从左右两边开始裁剪
    fill 填充整个容器,不会发生裁剪。(除非drawable的level是 0,才会不可见,表示全部裁剪完)。
    fill_vertical 垂直方向上不发生裁剪。(除非drawable的level是 0,才会不可见,表示全部裁剪完)
    fill_horizontal 水平方向上不发生裁剪。(除非drawable的level是 0,才会不可见,表示全部裁剪完)
    clip_vertical 附加选项,表示竖直方向的裁剪,很少使用
    clip_horizontal 附加选项,表示水平方向的裁剪,很少使用
    <?xml version="1.0" encoding="utf-8"?>
    <clip xmlns:android="http://schemas.android.com/apk/res/android"
          android:clipOrientation="horizontal"
          android:drawable="@drawable/ic_launcher"
          android:gravity="right">
    </clip>
    

    上边代码定义了一个 ClipDrawable 对象,设置进行水平方向裁剪,并且从左边开始裁剪。drawable为app启动图标。

    在布局文件的view中使用像 android:background="@drawable/clip" 代码来使用上边定义的 ClipDrawable。

    在java代码中,通过设置 ClipDrawble 的 level 属性的值,来进行图片背景的裁剪。

    linearLayout = (LinearLayout) findViewById(R.id.lll);
    linearLayout.getBackground().setLevel(5000); // 裁剪一半,0~10000
    

    效果如下图:

    裁剪

    九、InsetDrawable

    InsetDrawable 用距离边框的距离表示drawable大小,比如我们需要让view的背景不是完全填充这个view,并且需要一定的距离,就可以使用 InsetDrawable 来完成。InsetDrawable 对应xml文件中的 <inset/> 标签。

    属性:

    属性 参数类型 说明
    android:drawable drawable 对应drawable,可以为color、bitmap、shape等单一drawable
    android:inset dimen 统一设置距离边框的距离
    android:insetTop dimen 设置距容器上边的距离
    android:insetBottom dimen 设置距容器下边的距离
    android:insetLeft dimen 设置距容器左边的距离
    android:insetRight dimen 设置距容器右边的距离
    android:visible boolean 设置是否可见
    <?xml version="1.0" encoding="utf-8"?>
    <inset xmlns:android="http://schemas.android.com/apk/res/android"
           android:drawable="@color/colorAccent"
           android:inset="10dp">
    </inset>
    

    十、RippleDrawable

    RippleDrawable 可以在Android5.0 即 API21 以上实现波纹点击效果,对应xml文件中的 <ripple/> 标签。由于此标签必须在API21以上才可以使用,我们也不能设置 minSdkVersion 为21,毕竟要适配更多的API版本,我们可以在建立一个 drawable-v21 的文件夹,在里面新建一个xml文件即可。

    在Android studio中,就更方便了,选中 Drawable 文件夹--->右键--->选择new--->单击 Drawable resource file 选项,就来到了如下对话框:

    新建资源文件

    填写文件名,选择最后一个Version,单击中间的表示向右的按钮,填写21,点击ok,就会自动生成对应文件和新建文件。

    <ripple/> 标签的属性:

    属性 参数类型 说明
    android:color color 波纹的颜色,会覆盖在背景上
    android:radius dimen 圆角,不太懂,设置大小效果都一样
    <?xml version="1.0" encoding="utf-8"?>
    <ripple xmlns:android="http://schemas.android.com/apk/res/android"
            android:color="@color/gray">
        <!--有界-->
        <item
            android:id="@android:id/mask"
            android:drawable="@color/gray"/>
    </ripple>
    

    需要注意的是 android:id="@android:id/mask",没有设置时,是无边界的波纹效果,添加后为有边界。

    波纹点击效果

    参考博文:

    领略千变万化的Android Drawable (一)

    领略千变万化的Android Drawable (二)

    Android样式的开发:drawable汇总篇

    参考视频教程:

    [慕课网]Android的各种Drawable讲解

    相关文章

      网友评论

      • 捡淑:马克
      • Android之路:总结的很棒.但是shape标签对应的可不是ShapeDrawable,而是GradientDrawable :grin: .

      本文标题:神奇的Drawable文件夹---背景图篇

      本文链接:https://www.haomeiwen.com/subject/ixsbsttx.html