Android Drawable详解

工作中也有整理知识点的习惯,不过之前整理的知识点都放到印象笔记里面了,今天打算把这些内容拿出来与大家分享。内容不全的话请大家补充哈。
先放上两个写的比较好的博文:http://keeganlee.me/post/android/20150916
http://blog.csdn.net/ouyang_peng/article/details/8800743

OK,废话不多说,上代码

- animation_list标签:

oneshot:是否播放一次就结束
variablePadding: 选择true时,drawable的内边距会根据状态的变化而变化,设置为true时,你必须为不同的状态配置layout,但是通常不建议这么做。选择false时,内边距保持一致,所有状态中最大的内边距。默认为false

<animation-list xmlns:android="http://schemas.android.com/apk/res/android"

android:oneshot="true"

android:variablePadding="true">


<item

android:drawable="@drawable/loading_0"

android:duration="100" />

<item

android:drawable="@drawable/loading_1"

android:duration="100" />

<item

android:drawable="@drawable/loading_2"

android:duration="100" />

<item

android:drawable="@drawable/loading_3"

android:duration="100" />

<item

android:drawable="@drawable/loading_4"

android:duration="100" />

<item

android:drawable="@drawable/loading_5"

android:duration="100" />

<item

android:drawable="@drawable/loading_6"

android:duration="100" />

<item

android:drawable="@drawable/loading_7"

android:duration="100" />

</animation-list>
布局文件中可以加入如下代码测试效果
<ImageView

android:id="@+id/iv_animation_list"

android:layout_width="100dp"

android:layout_height="100dp"

android:src="@drawable/animation_list_drawable" />

Activity中的代码

AnimationDrawable animationDrawable = (AnimationDrawable) iv_animation_list.getDrawable();

animationDrawable.start();

- . bitmap标签:

可以通过bitmap标签对图片做一些设置,如平铺、拉伸或保持图片原始大小,也可以指定对齐方式。
看看bitmap标签的一些属性吧:

android:src 必填项,指定图片资源,只能是图片,不能是xml定义的drawable

android:gravity 设置图片的对齐方式,比如在layer-list中,默认会尽量填满整个视图,导致图片可能会被拉伸,为了避免被拉伸,就可以设置对齐方式,可取值为下面的值,多个取值可以用 | 分隔:

    top 图片放于容器顶部,不改变图片大小

    bottom 图片放于容器底部,不改变图片大小

    left 图片放于容器左边,不改变图片大小

    right 图片放于容器右边,不改变图片大小

    center 图片放于容器中心位置,包括水平和垂直方向,不改变图片大小

    fill 拉伸整张图片以填满容器的整个高度和宽度,默认值

    center_vertical 图片放于容器垂直方向的中心位置,不改变图片大小

    center_horizontal 图片放于容器水平方向的中心位置,不改变图片大小

    fill_vertical 在垂直方向上拉伸图片以填满容器的整个高度

    fill_horizontal 在水平方向上拉伸图片以填满容器的整个宽度

    clip_vertical 附加选项,裁剪基于垂直方向的gravity设置,设置top时会裁剪底                      部,设置bottom时会裁剪顶部,其他情况会同时裁剪顶部和底部

    clip_horizontal 附加选项,裁剪基于水平方向的gravity设置,设置left时会裁剪    右侧,设置right时会裁剪左侧,其他情况会同时裁剪左右两侧

    android:antialias 设置是否开启抗锯齿

android:dither 设置是否抖动,图片与屏幕的像素配置不同时会用到,比如图片是ARGB 8888的,而屏幕是RGB565

android:filter 设置是否允许对图片进行滤波,对图片进行收缩或者延展使用滤波可以获得平滑的外观效果

android:tint 给图片着色,比如图片本来是黑色的,着色后可以变成白色

android:tileMode 设置图片平铺的方式,取值为下面四种之一:

    disable 不做任何平铺,默认设置

    repeat 图片重复铺满

    mirror 使用交替镜像的方式重复图片的绘制

    clamp 复制图片边缘的颜色来填充容器剩下的空白部分,比如引入的图片如果是白色的边缘,那么图片所在的容器里除了图片,剩下的空间都会被填充成白色

android:alpha 设置图片的透明度,取值范围为0.0~1.0之间,0.0为全透明,1.0为全不透明,API Level最低要求是11,即Android 3.0

android:mipMap 设置是否可以使用mipmap,但API Level最低要求是17,即Android 4.2

android:autoMirrored 设置图片是否需要镜像反转,当布局方向是RTL,即从右到左布局时才有用,API Level 19(Android 4.4)才添加的属性

android:tileModeX 和tileMode一样设置图片的平铺方式,只是这个属性只设置水平方向的平铺方式,这是API Level 21(Android 5.0)才添加的属性

android:tileModeY 和tileMode一样设置图片的平铺方式,只是这个属性只设置垂直方向的平铺方式,这是API Level 21(Android 5.0)才添加的属性

android:tintMode 着色模式,也是API Level 21(Android 5.0)才添加的属性

<bitmap xmlns:android="http://schemas.android.com/apk/res/android"

android:antialias="true"

android:dither="true"

android:gravity="center"

android:src="@drawable/ic_launcher"

android:tileMode="mirror"

android:tint="@color/colorAccent" />

- clip标签:

ClipDrawable 是对一个Drawable进行剪切操作,可以控制这个drawable的剪切区域,以及相相对于容器的对齐方式,android中的进度条就是使用一个ClipDrawable实现效果的,

它根据level的属性值,决定剪切区域的大小。在xml文件中使用clip作为根节点定义ClipDrawable。

需要注意的是ClipDrawable是根据level的大小控制图片剪切操作的,官方文档的note中提到:The drawable is clipped completely and not visible when the level is 0 and fully revealed when the level is 10,000。也就是level的大小从0到10000,level为0时完全不显示,为10000时完全显示。是用Drawable提供的setLevel(int level)方法来设置剪切区域。

<clip xmlns:android="http://schemas.android.com/apk/res/android"

android:clipOrientation="vertical"

android:drawable="@drawable/ic_launcher"

android:gravity="right"></clip>
layout中代码:
<ImageView

android:id="@+id/iv_clip"

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:src="@drawable/clip_drawable" />
Activity代码中

final ClipDrawable clipDrawable = (ClipDrawable) iv_clip.getDrawable();

Observable.range(0, 10000).subscribeOn(Schedulers.io())

.observeOn(AndroidSchedulers.mainThread())

.subscribe(new Action1<Integer>() {

@Override

public void call(Integer aLong) {

clipDrawable.setLevel(Integer.parseInt(String.valueOf(aLong)));

}, new Action1<Throwable>() {

@Override

public void call(Throwable throwable) {

throwable.printStackTrace();

}

});

- color标签

ColorDrawable 是最简单的Drawable,它实际上是代表了单色可绘制区域,它包装了一种固定的颜色,当ColorDrawable被绘制到画布的时候会使用颜色填充Paint,在画布上绘制一块单色的区域。

<color xmlns:android="http://schemas.android.com/apk/res/android"

android:color="@color/colorAccent" />
  • insert标签

    InsetDrawable 表示一个drawable嵌入到另外一个drawable内部,并且在内部留一些间距,这一点很像drawable的padding属性,区别在于padding表示drawable的内容与drawable本身的边距,insetDrawable表示两个drawable和容器之间的边距。当控件需要的背景比实际的边框小的时候比较适合使用InsetDrawable。

<inset xmlns:android="http://schemas.android.com/apk/res/android"

android:drawable="@drawable/shape_drawable"

android:inset="10dp"/>

- layer_list_drawable 标签

LayerDrawable 管理一组drawable,每个drawable都处于不同的层,当它们被绘制的时候,按照顺序全部都绘制到画布上。虽然这些drawable会有交差或者重叠的区域,但是它们是位于不同的层,彼此之间不会影响。

在xml文件中使用layer-list作为根节点来定义LayerDrawable,通过item子节点定义每一层的drawable,layer-list没有属性节点,只包含item子节点。

<layer-list xmlns:android="http://schemas.android.com/apk/res/android">

<item

android:left="20dp"

android:right="20dp">

<shape android:shape="rectangle">

<corners android:radius="10dp" />

<stroke

android:width="2dp"

android:color="@color/colorAccent" />

<gradient

android:centerColor="@color/colorAccent"

android:endColor="@color/colorPrimary"

android:startColor="@color/colorCenter" />

</shape>

</item>

<item

android:left="20dp"

android:right="20dp">

<shape android:shape="rectangle">

<gradient

android:centerColor="@android:color/white"

android:startColor="@android:color/holo_red_light"

android:type="sweep" />

<corners android:radius="80dp" />

</shape>

</item>

</layer-list>

- level_list标签

当需要在一个View中显示不同图片的时候,比如手机剩余电量不同时显示的图片不同,level-list就可以派上用场了。level-list可以管理一组drawable,每个drawable设置一组level范围,最终会根据level值选取对应的drawable绘制出来。level-list通过添加item子标签来添加相应的drawable,其下的item只有三个属性:

android:drawable 指定drawable资源,如果不设置该属性,也可以定义drawable类型的子标签

android:minLevel 该item的最小level值

android:maxLevel 该item的最大level值

例如:setLevel(7000) 则会匹配第三个item

<level-list xmlns:android="http://schemas.android.com/apk/res/android">


<item

android:drawable="@drawable/clip_drawable"

android:maxLevel="4000"

android:minLevel="0" />

<item

android:drawable="@drawable/rotate_drawable"

android:maxLevel="6000"

android:minLevel="4000" />

<item

android:drawable="@drawable/scale_drawable"

android:maxLevel="10000"

android:minLevel="6000" />

</level-list>

- rotate标签

android:drawable Drawable 资源。必须的。引用一个drawable资源。

android:visible Boolean。是否可见。

android:fromDegrees 整形。 从多少的角度开始旋转

android:toDegrees 整形。 到多少的角度结束旋转

android:pivotX 百分比。 旋转的中心在图片X轴的百分比

android:visible 百分比。 旋转的中心在图片Y轴的百分比

注意这个不是动画,不存在旋转速度这一说,leveal最大为10000,在java代码可以设置当前的leveal

<rotate xmlns:android="http://schemas.android.com/apk/res/android"

android:drawable="@drawable/shape_drawable"

android:fromDegrees="0"

android:pivotX="50%"

android:pivotY="50%"

android:toDegrees="180"

android:visible="true">

</rotate>
Layout中:

<ImageView

android:id="@+id/iv_rotate"

android:layout_width="100dp"

android:layout_height="100dp"

android:src="@drawable/rotate_drawable" />
Activity中(下面的demo中用到了Rxjava):
Observable.range(0, 10000).subscribeOn(Schedulers.io())

.observeOn(AndroidSchedulers.mainThread())

.subscribe(new Action1<Integer>() {

@Override

public void call(Integer aLong) {

rotateDrawable.setLevel(aLong);

}

}, new Action1<Throwable>() {

@Override

public void call(Throwable throwable) {

throwable.printStackTrace();

}

});

- scale标签

drawable:Drawable 资源。必须的。引用一个drawable资源。

scaleGravity:指定缩放后gravity的位置 必须是下面的一个或多个值(多个值之间用”|“分隔),下面的值和描述和上一篇的ClipDrawable一样。

值 描述

top Put the object at the top of its container, not changing its size.

bottom Put the object at the bottom of its container, not changing its size.

left Put the object at the left edge of its container, not changing its size. This is thedefault.

right Put the object at the right edge of its container, not changing its size.

center_vertical Place object in the vertical center of its container, not changing its size.

fill_vertical Grow the vertical size of the object if needed so it completely fills its container.

center_horizontal Place object in the horizontal center of its container, not changing its size.

fill_horizontal Grow the horizontal size of the object if needed so it completely fills its container.

center Place the object in the center of its container in both the vertical and horizontal axis, notchanging its size.

fill Grow the horizontal and vertical size of the object if needed so it completely fills itscontainer.

clip_vertical Additional option that can be set to have the top and/or bottom edges of the child clipped toits container’s bounds. The clip is based on the vertical gravity: a top gravity clips thebottom edge, a bottom gravity clips the top edge, and neither clips both edges.

clip_horizontal Additional option that can be set to have the left and/or right edges of the child clipped toits container’s bounds. The clip is based on the horizontal gravity: a left gravity clipsthe right edge, a right gravity clips the left edge, and neither clips both edges.

scaleHeight:缩放的高度,用百分比的形式例如100%,80%代表从高度的80%开始缩放 level=0表示不可见 scaleWidth:缩放的宽度,同scaleHeight

leveal为0-10000用java代码setleveal来控制当前的leveal

<scale xmlns:android="http://schemas.android.com/apk/res/android"

android:drawable="@drawable/ic_launcher"

android:scaleGravity="left"

android:scaleHeight="80%"

android:scaleWidth="80%" />
<ImageView

android:id="@+id/iv_scale"

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:src="@drawable/scale_drawable" />
Observable.range(0, 10000).subscribeOn(Schedulers.io())

.observeOn(AndroidSchedulers.mainThread())

.subscribe(new Action1<Integer>() {

@Override

public void call(Integer aLong) {

scaleDrawable.setLevel(Integer.parseInt(String.valueOf(aLong)));

}

}, new Action1<Throwable>() {

@Override

public void call(Throwable throwable) {

throwable.printStackTrace();

}

});

- selector标签:


selector标签,可以添加一个或多个item子标签,而相应的状态是在item标签中定义的。

定义的xml文件可以作为两种资源使用:

drawable和color。作为drawable资源使用时,一般和shape一样放于drawable目录下,item必须指定android:drawable属性;

作为color资源使用时,则放于color目录下,item必须指定android:color属性。

android:state_enabled: 设置触摸或点击事件是否可用状态,一般只在false时设置该属性,表示不可用状态

android:state_pressed: 设置是否按压状态,一般在true时设置该属性,表示已按压状态,默认为false

android:state_selected: 设置是否选中状态,true表示已选中,false表示未选中

android:state_checked: 设置是否勾选状态,主要用于CheckBox和RadioButton,true表示已被勾选,false表示未被勾选

android:state_checkable: 设置勾选是否可用状态,类似state_enabled,只是state_enabled会影响触摸或点击事件,而state_checkable影响勾选事件

android:state_focused: 设置是否获得焦点状态,true表示获得焦点,默认为false,表示未获得焦点

android:state_window_focused: 设置当前窗口是否获得焦点状态,true表示获得焦点,false表示未获得焦点,例如拉下通知栏或弹出对话框时,当前界面就会失去焦点;

另外,ListView的ListItem获得焦点时也会 触发true状态,可以理解为当前窗口就是ListItem本身

android:state_activated: 设置是否被激活状态,true表示被激活,false表示未激活,API Level 11及以上才支持,可通过代码调用控件的setActivated(boolean)方法设置是否激活该控件

android:state_hovered: 设置是否鼠标在上面滑动的状态,true表示鼠标在上面滑动,默认为false,API Level 14及以上才支持

<selector xmlns:android="http://schemas.android.com/apk/res/android">

<item android:drawable="@drawable/loading_0" android:state_enabled="true" />

<item android:drawable="@drawable/ic_launcher" android:state_pressed="true" />

<item android:drawable="@drawable/shape_drawable" android:state_selected="true" />

<item android:drawable="@color/colorCenter" android:state_checked="true" />

<item android:drawable="@android:color/holo_red_dark" android:state_checkable="true" />

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

<item android:drawable="@color/colorAccent" android:state_window_focused="true" />

<item android:drawable="@android:color/background_dark" android:state_active="true" />

<item android:drawable="@android:color/darker_gray" android:state_hovered="true" />

</selector>

- shape标签

用xml实现一些形状图形, 或则颜色渐变效果,相比PNG图片, 占用空间更小; 相比自定义View,实现起来更加简单rectangle 长方形 /默认oval 椭圆line 线ring 环形

<shape xmlns:android="http://schemas.android.com/apk/res/android"

android:shape="rectangle">


corners标签: 圆角

bottomLeftRadius 左下角

bottomRightRadius 右下角

topLeftRadius 左上角

topRightRadius 右上角

radius 是四个角, 设置了这个就不需要设置上面的四个了, PS:它的优先级比较低, 会被其他参数覆盖

<corners

android:bottomLeftRadius="3dp"

android:bottomRightRadius="3dp"

android:radius="5dp"

android:topLeftRadius="5dp"

android:topRightRadius="5dp" />


gradient标签:简单来说就是让图形变成一个有颜色梯度的

angle: 是颜色变换的角度, 默认是0, 取值必须是45的 倍数. 0: 是颜色从左边到右边, 90: 是颜色从底部到顶部

startColor centerColor endColor 一起使用: 开始的颜色, 中间的颜色, 结束的颜色

centerX centerY是指定位置坐标, 取值是0.0f ~ 1.0f 之间, 例如: android:centerX="0.5f" 表示X方向的中间位置

type 颜色渐变的类型, 取值类型有三种: linear/radial/sweep

linear 线性变化, 就是颜色从左往右, 从下往上

radial 放射变化, 例如: 从一个圆中心到圆的边缘变化

sweep 扫描式渐变, 类似雷达扫描的那种图形

gradientRadius 和android:type="radial"一起连用, 半径

useLevel 是否被用作 LevelListDrawable.

<gradient

android:angle="90"

android:centerColor="@color/colorCenter"

android:centerX="0.5"

android:centerY="0.5"

android:endColor="@color/colorPrimaryDark"

android:gradientRadius="5dp"

android:startColor="@color/colorAccent"

android:type="linear"

android:useLevel="true" />


padding标签: 这里的padding是控件中间内容与shape图形图片的距离

<padding

android:bottom="5dp"

android:left="5dp"

android:right="5dp"

android:top="5dp" />


size标签 shape图形的宽度和高度 这里一般不用设置, 它的优先级没有控件的优先级大,

他指定控件的宽高就好, shape图形会随控件拉伸

<size

android:width="30dp"

android:height="30dp" />


solid标签: shape图形背景色

PS: 这个和上面的gradient标签会互斥, 一个是设置背景色, 一个是设置渐变色, 你懂得

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


stroke标签: 边框

width 边框的宽度

color 边框的颜色

下面两个参数是 把边框变成虚线用

dashGap 虚线中空格的长度

dashWidth 虚线中实线的长度

<stroke

android:width="0.5dp"

android:color="@color/colorPrimary"

android:dashGap="3dp"

android:dashWidth="3dp" />

</shape>

- transition标签:

transition其实是继承自layer-list的,只是,transition只能管理两层drawable,另外提供了两层drawable之间切换的方法,切换时还会有淡入淡出的动画效果。

<transition xmlns:android="http://schemas.android.com/apk/res/android">

<item android:drawable="@drawable/xrefresh_ok" />

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

</transition>


transition标签生成的Drawable对应的类为TransitionDrawable,要切换时,需要主动调用TransitionDrawable的startTransition()方法,

参数为动画的毫秒数,也可以调用reverseTransition()方法逆向切换。

((TransitionDrawable)drawable).startTransition(500); 正向切换,即从第一个drawable切换到第二个(这里说的切换仅仅是指谁在上面的问题,不涉及到隐藏显示的问题)

((TransitionDrawable)drawable).reverseTransition(500); 逆向切换,即从第二个drawable切换回第一个


TransitionDrawable transitionDrawabl = (TransitionDrawable) iv_transition.getDrawable();

transitionDrawabl.reverseTransition(4000);
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值