美文网首页
【总结】Drawable的用法,shape以外的部分

【总结】Drawable的用法,shape以外的部分

作者: 械勒的时间 | 来源:发表于2018-05-08 14:47 被阅读0次

drawable 文件夹中,最常用的文件其实只有三种,分别是shape,selector,跟9patch图。
鉴于篇幅原因,shape单独拿出来写,剩余的包括selector,9patch图在内的六七种文件类型合成一篇来写。

BitmapDrawable

想不到吧,最基本的图片也能包一层xml文件来用,但这一层xml当然不是白写的,它能提供更强大的图片属性支持。
比如它最大的作用是,当把图片作为背景图使用的时候,不只有拉伸一种填充方式。


<?xml version="1.0" encoding="utf-8"?>
<bitmap xmlns:android="http://schemas.android.com/apk/res/android"
    android:antialias="true"
    android:dither="true"
    android:filter="true"
    android:gravity="center"
    android:mipMap="false"
    android:src="@mipmap/ic_android"
    android:tileMode="disabled" />

    <!--
    antialias 抗锯齿功能,会使图片变得平滑,推荐开启,虽说会降低图片的清晰度,但是这个可以忽略
    dither 图片防失真,推荐开启。防止屏幕支持的色彩模式比图片自身的色彩模式差时,图片失真
    filter 开启过滤效果,推荐开启。当图片被拉伸或者压缩的时候,可以保证较好的显示效果。
    gravity 图片定位选项,比较多,下文细说。
    mipmap 是一种图像相关的处理技术,叫做纹理映射,默认false,平时不常用。
    src 是图片资源id,这个必须有
    tileMode 这个是图片的平铺方式,有一下四个选项,disable clamp repeat mirror
    -->

gravity 可用属性以及含义
top 将图片置顶,大小不变
bottom 将图片置底,大小不变
left 将图片放在控件左侧,大小不变
right 将图片放在控件右侧,大小不变
center_vertical 使图片垂直居中,大小不变
fill_vertical 使图片在垂直方向上填充控件
center_horizontal 使图片水平居中,大小不变
fill_horizontal 使图片在水平方向上填充控件
center 将图片置于中心位置,大小不变
fill 使图片完全填充控件,这个是默认值
clip_vertical 当控件垂直大小小于图片大小时,图片垂直方向剪裁,单独使用时,图片默认居中
clip_horizontal 当控件水平大小小于图片大小时,图片水平方向剪裁,单独使用时,图片默认居中

需要注意的是,gravity只有当tileMode属性为disable时,才会生效。
而tileMode 属性的 repeat mirror 属性在做纹理背景时,非常实用。
tileMode 属性其他三个选项的效果如下图,其中ImageView的宽高属性均为填充。

从左到右分别是disable clamp repeat mirror.png

NinePatchDrawable

又被称作是.9图或者9Patch图,开发中很实用的一个图片类型,可以降低我们卡发人员的适配难度。最常见的使用场景是对话框的框体。

9Patch图也可以加一层xml文件来使用,但是相比较与普通图片的极大增强,9Patch图只能增加一个 dither 图片防失真的属性,因此平时使用中我们都会直接使用。

9Patch图的边框线有两种,一种是黑色线,左侧,上侧两部分的黑线表示可拉伸区域,在View与图片大小不符合的时候,这两部分会拉伸以适应View的大小。
右侧,下侧部分黑线表示可显示区域,就是说,假设这个9Patch图是用作TextView的背景图使用,文字只会显示在右侧,下侧黑线重叠区域,类似于shape的Padding,但是可以被TextView的padding属性覆盖。

9Patch图还有一种红色的线,我没有使用过,也不明白是做什么用的,若您知道,请告诉我,感激不尽。

做9Patch图我比较喜欢将其重命名为xxx.9.png之后直接复制到drawable文件夹中,然后使用android studio 自带的工具对其进行画线,直接画线为黑色线,按住shift为擦除,按住ctrl为红色线,并且通过实时预览功能来确定是否为我想要的样子。不要使用任何插件/工具来完成这个步骤,太麻烦没必要。

StateListDrawable

这也是常用文件的一种,对应于<selector>标签的xml文件。


<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android"
    android:constantSize="false"
    android:dither="true"
    android:variablePadding="false">
    <!--
    selector的特性是会随着状态的改变而切换到具体的drawable
    constantSize,表明切换到具体的drawable时,其大小是否会保持固有大小,默认为false
            true,表明保持固有大小了,为所有drawable的固有大小的最大值
            false,表明不保持固有大小,每切换到具体的drawable时使用当前drawable的大小
    dither,图片防失真,默认为true
    variablePadding,表明padding是否保持固有大小,类似于constantSize,默认为false
            true,表明保持固有大小了
            false,表明不保持固有大小
    -->
    
    <item android:drawable="@drawable/ic1"
        android:state_checkable="true"
        android:state_checked="true"
        android:state_enabled="true"
        android:state_focused="true"
        android:state_pressed="true"
        android:state_selected="true"/>
</selector>

selector中,item的状态一共有17种,选取常用的6个说明其含义

item的状态以及含义
state_checkable 表示是否可选中,常见于CheckBox这种选择器中
state_checked 表示是否被选中,常见于CheckBox这种选择器中
state_enabled 表示是否处于可用状态
state_focused 表示是否获取了焦点
state_pressed 表示是否被按下
state_selected 表示是否被选择

PS:平时开发时,我们常常会使用<selector>标签来实现不同状态时,显示不同图片的效果,但这是很不专业的一个写法,虽然说这么写也可以达到我们的预期,但是稍有不慎却会导致程序显示异常,严重情况甚至会崩溃。对于这种效果,我推荐使用<level-list>标签来实现。

LevelListDrawable

对应于<level-list>标签,它表示一个drawable的集合,其中每一个drawable对应一个或者多个等级,我们通过设置View的等级来切换drawable。
<level-list>标签是安卓推荐的设置图片集合的一个方式,而不是使用<selector>标签。


<?xml version="1.0" encoding="utf-8"?>
<level-list xmlns:android="http://schemas.android.com/apk/res/android">
    <item
        android:drawable="@mipmap/ic_1"
        android:maxLevel="0"
        android:minLevel="10" />
    <item
        android:drawable="@mipmap/ic_2"
        android:maxLevel="11"
        android:minLevel="20" />
</level-list>

之后通过设置level属性来切换图片。
ImageView可以使用setImageLevel()来切换其src对应的图片,
其他View背景图统一使用getBackground().setLevel()来切换背景图片。


        imageView.setImageLevel(0);
        view.getBackground().setLevel(0);

使用的时候一定要保证每个<item>标签之间的level范围不重合,level的值不能为负数,且顺序要么为升序,要么为降序,不能为乱序。为View设置level值时,有且只有一个<item>标签与其对应,否则会出现显示效果达不到预期的情况,甚至不会显示。

平时使用的时候,可以忽略<item>标签中的minLevel属性,将其简写为


<?xml version="1.0" encoding="utf-8"?>
<level-list xmlns:android="http://schemas.android.com/apk/res/android">
    <item
        android:drawable="@mipmap/ic_1"
        android:maxLevel="1" />
    <item
        android:drawable="@mipmap/ic_2"
        android:maxLevel="2" />
</level-list>


TransitionDrawable

对应于<transition>标签,用于实现两张图片淡入淡出的效果,可用于ImageView的资源图片,或者其他View的背景。


<?xml version="1.0" encoding="utf-8"?>
<transition xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:drawable="@mipmap/bg1" />
    <item android:drawable="@mipmap/bg2" />
</transition>

<!--item的属性包括,宽高以及左右边距,因为都是常见的属性,所以不做解释了-->

<item
        android:bottom="10dp"
        android:height="100dp"
        android:width="100dp"
        android:drawable="@mipmap/bg1"
        android:left="10dp"
        android:right="10dp"
        android:top="10dp" />

将TransitionDrawable设置为View的背景或者ImageView的显示图片后,可以通过以下方式获取到该TransitionDrawable,并且进行淡入淡出动画。


transitionDrawable = (TransitionDrawable) view.getBackground();
transitionDrawable = (TransitionDrawable) imageView.getDrawable();

transitionDrawable.startTransition(1000);
transitionDrawable.reverseTransition(1000);

InsetDrawable

对应于<inset>标签,可以对一张图片增加上下左右的padding,一般用于背景比实际显示的区域小的时候。
相对于<layer-list>标签,<inset>标签看起来更加简单,不过实现这种效果时我比较喜欢用<layer-list>标签来实现。


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

    <!--使用时,可以直接指定drawable,或者内嵌其他Drawable文件,比如shape-->
    <shape android:shape="rectangle"></shape>

</inset>

为View设置背景时,View的padding会默认为<inset>标签内写入的内边距值,此时重新指定当前View的padding,便可达到预期。

重新指定padding,文字便会回到边上

还有两个

他们分别是
ScaleDrawable
对应于<scale>标签,用来对一张图片进行缩放。
ClipDrawable
对应于<clip>标签,用来实现对一张图片的剪裁。

由于通过它对图片的剪裁效果并不直观,不如让UI同学切图来得快,每次用完都会让UI同学一顿锤,所以我不怎么喜欢用,此处不表。


个人理解,难免有错误纰漏,欢迎指正。转载请注明出处。

相关文章

网友评论

      本文标题:【总结】Drawable的用法,shape以外的部分

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