Drawable有很多种,它们都表示一种图像的概念,但是它们又不全是图片,通过颜色也可以构造出各式各样的图像的效果。在实际开发中,Drawable常被用来作为View的背景使用。Drawable一般都是通过XML来定义的,当然我们也可以通过代码来创建具体的Drawable对象,只是用代码创建会稍显复杂。在Android的设计中,Drawable是一个抽象类,它是所有Drawable对象的基类,每个具体的Drawable都是它的子类。本文将对Drawable的子类进行一一讲解,减少您的开发时间。
BitmapDarawable
使用BitmapDarawable实现效果
介绍
一个可绘制的位图,可以平铺,拉伸或对齐。 您可以从文件路径,输入流,XML填充或位图对象创建一个BitmapDrawable。它可以使用元素在XML文件中定义。该类处理原始位图图形的管理和转换,并应在绘制到“画布”时使用,bitmapdrawable 语法相对简单
<?xml version="1.0" encoding="utf-8"?>
<bitmap xmlns:android="http://schemas.android.com/apk/res/android"
android:antialias=
android:src="@[package:]drawable/drawable_resource"["true" | "false"]
android:dither=["true" | "false"]
android:filter=["true" | "false"]
android:gravity=["top" | "bottom"|"left"|"right" | "center_vertical" | "fill_vertical"|"center_horizontal" | "fill_horizontal" |"center" | "fill" | "clip_vertical" | "clip_horizontal"]
android:mipMap=["true" | "false"] android:tileMode=["disabled" | "clamp" | "repeat" | "mirror"] />
android:src
- 添加图片资源id
android:antialias (是否开启图片抗锯齿功能)
启用或禁用抗锯齿。 旋转时,可以使用抗锯齿来平滑位图的边缘。 默认值是false。
可能是一个布尔值,如“true”或“false”。
开启后会让图片变得光滑,但是可以忽略的降低图片的清晰度。
android:dither (是否开启防抖动效果)
当图片的像素配置和手机屏幕的像素配置不一致时,开启这个可以让高质量的图片在低质量的屏幕上还有较好的显示效果。(默认是开启的,建议开启)
android:filter (是否开启过滤效果)
android:tileMode
平铺模式。这个选项有如下几个值:[“disabled”|“clamp”|“repeat”|“mirror”],其中disable表示关闭平铺模式,这也是默认值,当开启平铺模式后,gravity属性会被忽略。
刚我们看见的为mirror属性,下图分别为 clamp,repeat 两个个属性。
ShapeDrawable
用ShapeDrawable实现效果图
介绍
ShapeDrawable是一种很常见的Drawable,可以理解为通过颜色来构造的图形,它既可以是纯色的图形,也可以是具有渐变效果的图形。ShapeDrawable的语法相对于bitmapdrawable 较为复杂。
<?xml version="1.0" encoding="utf-8"?>
<shape
xmlns:android="http://schemas.android.com/apk/res/android"
android:shape=["rectangle" | "oval" | "line" | "ring"] >
<corners
android:radius="integer"
android:topLeftRadius="integer"
android:topRightRadius="integer"
android:bottomLeftRadius="integer"
android:bottomRightRadius="integer" />
<gradient
android:angle="integer"
android:centerX="float"
android:centerY="float"
android:centerColor="integer"
android:endColor="color"
android:gradientRadius="integer"
android:startColor="color"
android:type=["linear" | "radial" | "sweep"]
android:useLevel=["true" | "false"] />
<padding
android:left="integer"
android:top="integer"
android:right="integer"
android:bottom="integer" />
<size
android:width="integer"
android:height="integer" />
<solid
android:color="color" />
<stroke
android:width="integer"
android:color="color"
android:dashWidth="integer"
android:dashGap="integer" />
</shape>
android:shape 对应属性内容如下:
rectangle | oval | line | ring |
---|---|---|---|
矩形 | 椭圆 | 横线 | 圆环 |
corners 标签
- android:radius——为四个角同时设定相同的角度,优先级较低,会被其他四个属性覆盖;
- android:topLeftRadius-: 设定最上角的角度 integer
- android:topRightRadius—: 设定右上角的角度 integer
- android:bottomLeftRadius—: 设定最下角的角度 integer
- android:bottomRightRadius—: 设定右下角的角度 integer
gradient标签
它与标签是互相排斥的,其中solid表示纯色填充,而gradient则表示渐变效果,gradient有如下几个属性:
- android:angle——渐变的角度,默认为0,其值必须为45的倍数,0表示从左到右,90 表示从下到上,具体的效果需要自行体验,总之角度会影响渐变的方向
- android:centerX——渐变的中心点的横坐标
- android:centerY——渐变的中心点的纵坐标,渐变的中心点会影响渐变的具体效果
- android:startColor——渐变的起始色
- android:centerColor——渐变的中间色
- android:endColo——渐变的结束色
- android:gradientRadius——渐变半径,仅当**android:type= “radial”**时有效;
- android:type——渐变的类别,有linear(线性渐变)、radial(径向渐变)
stroke
stroke(边缘,有描边之意)
- android:width——描边的宽度,越大则shape的边缘线就会看起来越粗
- android:color——描边的颜色
- android:dashWidth——组成虚线的线段的宽度
- android:dashGap——组成虚线的线段之间的间隔,间隔越大则虚线看起来空隙就越大
上图中实现代码如下:
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<corners
android:radius="2dp"
/>
<gradient
android:angle="90"
android:centerColor="@color/colorPrimaryDark"
android:centerX="0"
android:centerY="0"
android:endColor="@color/colorAccent"
android:startColor="@color/colorPrimary"
android:type="linear" />
<!--<padding-->
<!--android:bottom="integer"-->
<!--android:left="integer"-->
<!--android:right="integer"-->
<!--android:top="integer" />-->
<!--纯色填充,与渐变冲突-->
<!--<solid android:color="color" />-->
<stroke
android:width="5dp"
android:color="@color/colorBlue"
android:dashGap="10dp"
android:dashWidth="20dp" />
</shape>
LayerDrawable
用LayerDrawable实现效果图
Layer(层次,层叠,图层)
LayerDrawable对应的XML标签是,它表示一种层次化的Drawable集合,通过将不同的Drawable放置在不同的层上面从而达到一种叠加后的效果。它的语法如下所示。
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:drawable="@[package:]drawable/drawable_resource"
android:id="@[+][package:]id/resource_name"
android:top="dimension"
android:right="dimension"
android:bottom="dimension"
android:left="dimension" />
</layer-list
一个layer-list中可以包含多个item,每个item表示一个Drawable。Item的结构也比较简单,比较常用的属性有android:top、android:bottom、android:left和android:right,它们分别表示Drawable相对于View的上下左右的偏移量,单位为像素。另外,我们可以通过android:drawable属性来直接引用一个已有的Drawable资源,也可以在item中自定义Drawable。默认情况下,layer-list中的所有的Drawable都会被缩放至View的大小,对于bitmap来说,需要使用android:gravity属性才能控制图片的显示效果。Layer-list有层次的概念,下面的item会覆盖上面的item,通过合理的分层,可以实现一些特殊的叠加效果。下面代码是实现上图的代码:
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item>
<bitmap android:src="@drawable/queen"
android:gravity="left" />
</item>
<item android:top="30dp" android:left="30dp">
<bitmap android:src="@drawable/queen"
android:gravity="left" />
</item>
<item android:top="60dp" android:left="60dp">
<bitmap android:src="@drawable/queen"
android:gravity="left" />
</item>
</layer-list>
StateListDrawable
StateListDrawable对应于标签,它也是表示Drawable集合,每个Drawable都对应着View的一种状态,这样系统就会根据View的状态来选择合适的Drawable。StateListDrawable主要用于设置可单击的View的背景,设置button背景颜色等,它的语法如下所示:
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android"
android:constantSize=["true" | "false"]
android:dither=["true" | "false"]
android:variablePadding=["true" | "false"] >
<item android:drawable="@[package:]drawable/drawable_resource"
android:state_pressed=["true" | "false"]
android:state_focused=["true" | "false"]
android:state_hovered=["true" | "false"]
android:state_selected=["true" | "false"]
android:state_checkable=["true" | "false"]
android:state_checked=["true" | "false"]
android:state_enabled=["true" | "false"]
android:state_activated=["true" | "false"]
android:state_window_focused=["true" | "false"] />
</selector>
其中item,可对应多个state标签,系统会根据当前view的状态,自动选择对应的item。
LevelListDrawable
LevelListDrawable对应于标签,它同样表示一个Drawable集合,集合中的每个Drawable都有一个等级(level)的概念。根据不同的等级,LevelListDrawable会切换为对应的Drawable,它的语法如下所示。
<?xml version="1.0" encoding="utf-8"?>
<level-list
xmlns:android="http://schemas.android.com/apk/res/android" >
<item android:drawable="@drawable/drawable_resource"
android:maxLevel="integer"
android:minLevel="integer" />
</level-list>
上面的语法中,每个item表示一个Drawable,并且有对应的等级范围,由android:min- Level和android:maxLevel来指定,在最小值和最大值之间的等级会对应此item中的Drawable。如果它被用来作为ImageView的前景Drawable,那么还可以通过ImageView的setImageLevel方法来切换Drawable。最后,Drawable的等级是有范围的,即0~10000,最小等级是0,这也是默认值,最大等级是10000。对应Imageview代码如下:
ImageView imageView = new ImageView(this);
imageView.setImageLevel(2000);
TransitionDrawable
上图从一张波点图片转到帆船照片的效果
TransitionDrawable对应于标签,它用于实现两个Drawable之间的淡入淡出效果,它的语法如下所示:
<?xml version="1.0" encoding="utf-8"?>
<transition xmlns:android="http://schemas.android.com/apk/res/android" >
<item
android:drawable="@[package:]drawable/drawable_resource"
android:id="@[+][package:]id/resource_name"
android:top="dimension"
android:right="dimension"
android:bottom="dimension"
android:left="dimension" />
</transition
上述效果实现代码如下:
首先先定义TransitionDrawable,为布局设置background。
<?xml version="1.0" encoding="utf-8"?>
<transition xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="@drawable/first" />
<item android:drawable="@drawable/second" />
</transition>
java代码如下
TransitionDrawable background = (TransitionDrawable)linearLayout.getBackground();
background.startTransition(1000);
最后:drawable 子类还有 ClipDrawable,InsetDrawable 等,这些我们不怎么常用,或者可通过上述drawable也可实现该效果,所以不一一介绍,另外我们可以自定义drawable。只需要继承Drawable类,复写 draw、setAlpha、setColorFilter和getOpacity几个方法即可。其中较为重要的为draw方法。