Drawable是什么?按照字面翻译,就是可绘制的,由于能够绘制的东西很多,所以,这个类是一个抽象类。
由于drawable可以在xml文件中进行配置,所以,这些标签都对应相应的Drawable子类,我们平时使用xml配置的drawable,其实系统解析时,也是使用的标签对应的Drewable的各个子类来创建drawable的。下面是标签和rewable的各个子类的对应关系
<adaptive-icon /> AdaptiveIconDrawable
<animated-image /> AnimatedImageDrawable
<animated-vector /> AnimatedVectorDrawable
<bitmap /> BitmapDrawable
<color /> ColorDrawable
<layer-list /> LayerDrawable
<shape /> GradientDrawable 或者 ShapeDrawable
<selector /> StateListDrawable
<level-list /> LevelListDrawable
<transition /> TransitionDrawable
<scale /> ScaleDrawable
<clip /> ClipDrawable
<rotate /> RotateDrawable
<animation-List /> AnimationDrawable
<inset /> InsetDrawable
<nine-patch /> NinePatchDrawable
<vector /> VectorDrawable
下面介绍下,介绍常用的一些在xml文件中配置drawable
例如BitmapDrawable在xml文件中的配置:
<?xml version="1.0" encoding="utf-8"?>
<bitmap xmlns:android="http://schemas.android.com/apk/res/android"
android:src="@drawable/具体资源名称"
android:antialias=["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"] />
</bitmap>
各个属性的取值的含义:
antialias :当取值为true时表示开启抗锯齿效果,这样图片的边缘会更平滑,取值为false表示关闭抗锯齿效果,一般建议开启。
dither:表示是否开启去抖动效果,当开启时,比如图片的色彩模式ARGB8888,但是设备的支持的测彩模式是RGB565,这个时候开启这个选项,可以让图片显示不过于失真,一般建议开启
filter:是否开启过滤效果。当图片的尺寸拉伸或者压缩时,开启会这个效果,可以较好的显示效果,一般建议开启。
gravity:当图片的尺寸小于容器的尺寸时,设置该属性,可以对图片进行定位,可以通过"|"来组合几种属性值一起使用。以下是各个取值的具体含义
mipMap:纹理映射,默认值为false。平时开发中很少用到。
titleMode:平铺模式,可以取值[“disabled”|“clamp”|“repeat”|“mirror”],其中disable表示关闭平铺模式,当开启平铺模式后,gravity这属性才起作用。
clamp 表示拉伸最后一个像素去铺满剩下的地方
repeat 重复图片,铺满父容器
mirror 通过镜像翻转铺满父容器剩下的地方
例如NinePatchDrawable表示的是一张.9格式的图片,在xml文件中的配置:
<?xml version="1.0" encoding="utf-8"?>
<nine-patch xmlns:android="http://schemas.android.com/apk/res/android"
android:src="@drawable/具体资源名称"
android:antialias=["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"]
</nine-patch>
例如ShapeDrawable在xml文件中的配置:
<?xml version="1.0" encoding="utf-8"?>
<shape
xmlns:android="http://schemas.android.com/apk/res/android"
android:shape=["rectangle" | "oval" | "line" | "ring"] //共有4种类型,矩形(默认)/椭圆形/直线形/环形
// 以下4个属性只有当类型为环形时才有效
android:innerRadius="dimension" //内环半径
android:innerRadiusRatio="float" //内环半径相对于环的宽度的比例,比如环的宽度为50,比例为2.5,那么内环半径为20
android:thickness="dimension" //环的厚度
android:thicknessRatio="float" //环的厚度相对于环的宽度的比例
android:useLevel="boolean"> //如果当做是LevelListDrawable使用时值为true,否则为false.
<corners //定义圆角
android:radius="dimension" //全部的圆角半径,优先级较低,会被其他四个属性覆盖
android:topLeftRadius="dimension" //左上角的圆角半径
android:topRightRadius="dimension" //右上角的圆角半径
android:bottomLeftRadius="dimension" //左下角的圆角半径
android:bottomRightRadius="dimension" /> //右下角的圆角半径
<gradient //定义渐变效果,与solid标签是互斥的
android:type=["linear" | "radial" | "sweep"] //共有3中渐变类型,线性渐变(默认)/放射渐变/扫描式渐变
android:angle="integer" //渐变角度,必须为45的倍数,0为从左到右,90为从上到下
android:centerX="float" //渐变中心X的相当位置,范围为0~1
android:centerY="float" //渐变中心Y的相当位置,范围为0~1
android:startColor="color" //渐变开始点的颜色
android:centerColor="color" //渐变中间点的颜色,在开始与结束点之间
android:endColor="color" //渐变结束点的颜色
android:gradientRadius="float" //渐变的半径,只有当渐变类型为radial时才能使用
android:useLevel=["true" | "false"] /> //使用LevelListDrawable时就要设置为true。设为false时才有渐变效果
<padding //内部边距,它表示的不是shape的空白,而是包含它的view的空白
android:left="dimension"
android:top="dimension"
android:right="dimension"
android:bottom="dimension" />
<size //自定义的图形大小,这个不是shape最终显示的大小,getIntrinsicWidth,getIntrinsicHeight获取的就是这里设置的值
android:width="dimension"
android:height="dimension" />
<solid //内部填充颜色
android:color="color" />
<stroke //描边
android:width="dimension" //描边的宽度
android:color="color" //描边的颜色
// 以下两个属性设置虚线
android:dashWidth="dimension" //虚线的宽度,值为0时是实线
android:dashGap="dimension" /> //虚线的间隔,间隔越大虚线看起来空隙就越大
</shape>
具体的属性值和BitmapDrawable一样,这里就不做重复的介绍,需要注意的是,src这里的资源
要是.9格式的图片。
LayerDrawable在xml文件中的配置信息:
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:drawable="@drawable/具体的资源名称"
android:top="dimension"
android:bottom="dimension"
android:left="dimension"
android:right="dimension">
<shape android:shape="rectangle">
<solid android:color="#ffffff"/>
</shape>
</item>
// 多个 item
</layer-list>
每个lay-list中可以包含多个item,每个item都表示一个drawable,后面的item会覆盖前面的item,layer-list中,所有的item都会被缩放至和View一样大小,item的属性top,bottom,left,right,表示drawable距离View的上下左右的距离,单位是px。下面的示例就是仿微信文本输入框的效果:
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item>
<shape android:shape="rectangle">
<solid android:color="#0ac39e"/>
</shape>
</item>
<!--距离view的bottom 6dp 绘制一个白色矩形-->
<item android:bottom="6dp">
<shape android:shape="rectangle">
<solid android:color="#ffffff"/>
</shape>
</item>
<!--距离view的bottom left right 1dp 绘制一个白色矩形-->
<item
android:bottom="1dp"
android:left="1dp"
android:right="1dp">
<shape android:shape="rectangle">
<solid android:color="#ffffff"/>
</shape>
</item>
</layer-list>
StateListDrawable在xml文件中的配置(只是包含了一些常见的):
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android"
android:constantSize=["true"|"false"] //StatListDrawable 固定大小是否随着其状态改变而改变,
//因为状态的改变会导致StateListDrawable切换到不同的drawable,
//而不同的drawable的固定大小不同,如果设置为true,那么StateListDrawable的大小就是
//它内部包含的所有drawable的固有大小的最大值,false表示StateListDrawable随着状态
//改变而改变固有大小。默认为false
android:dither=["true"|"false"] //是否开启抖动效果,默认为true
android:variablePadding=["true"|"false"]> //StateListDrawable的padding是否随着其状态的改变而改变,
//true表示会随着状态的改变而改变
//false表示StateListDrawable的padding是内部所有Drawable的padding的最大值,默认是false,
//建议不开启此项
<item android:state_pressed=["true"|"false"] android:drawable="@drawable/vx" /> <!--pressed-->
<item android:state_checkable=["true"|"false"] android:drawable="@drawable/wb"/> <!--checkable-->
<item android:state_focused=["true"|"false"] android:drawable="@drawable/qzone"/> <!--accelerated-->
<item android:state_hovered=["true"|"false"] android:drawable="@drawable/qq"/> <!--active-->
<item android:state_activated=["true"|"false"] android:drawable="@drawable/p1"/>
<item android:state_checked=["true"|"false"] android:drawable="p2"/>
<item android:state_selected=["true"|"false"] android:drawable="@drawable/p3"/>
<item android:state_enabled=["true"|"false"] android:drawable="@drawable/p4"/>
<item android:state_window_focused=["true"|"false"] android:drawable="@drawable/p5"/>
<item android:drawable="@drawable/p6"/> <!--default-->
</selector>
具体示例:
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_pressed="true" android:drawable="@drawable/vx" /> <!--pressed-->
<item android:drawable="@drawable/p6"/> <!--default-->
</selector>
系统会根据View当前的状态从Selector中选择对应的item,按照从上到下的顺序匹配,如果未找到匹配的item,则会使用默认的,所以建议默认的放到最后,如果将默认放到最上面,则就相当于是默认的匹配了任何的view的状态了,这就显示不出我们想要的效果了,读者可以自己试试,将本示例中的两个item的顺序更换一下,看看效果。
LevelListDrawable在xml文件的配置:
<?xml version="1.0" encoding="utf-8"?>
<level-list xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="@drawable/p5" android:maxLevel="integer" android:minLevel="integer"/>
<item android:drawable="@drawable/p3" android:maxLevel="integer" android:minLevel="integer"/>
</level-list>
每个item对应一个drawable,等级范围是0~10000,0是默认值,可以通过代码来调整等级来切换不同的drawable
代码示例:
var level = 100
my_iv_1.setImageLevel(level)
mybtn_1.setOnClickListener {
if(level == 100){
level = 45
}else{
level = 100
}
LogUtil.i(""+level)
my_iv_1.setImageLevel(level)
}
TransitionDrawable在xml文件中的配置:
<?xml version="1.0" encoding="utf-8"?>
<transition xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="@drawable/p1"/>
<item android:drawable="@drawable/p2"/>
</transition>
在代码中控制渐变:
val background : TransitionDrawable = my_tv_2.background as TransitionDrawable
background.startTransition(1000) //经过1秒钟,从p1这个drawable渐变成p2这个drawable
InsetDrawable在xml文件中的配置:
<inset xmlns:android="http://schemas.android.com/apk/res/android"
android:drawable="@drawable/具体资源名称"
android:insetLeft="dimension"
android:insetTop="dimension"
android:insetRight="dimension"
android:insetBottom="dimension">
</inset>
insetLeft,insetTop,insetRight,insetBottom分别表示向内凹的大小,让一个view的前景向内部凹16dp示例:
<?xml version="1.0" encoding="utf-8"?>
<inset xmlns:android="http://schemas.android.com/apk/res/android"
android:drawable="@drawable/wb"
android:insetLeft="@dimen/dp16"
android:insetTop="@dimen/dp16"
android:insetBottom="@dimen/dp16">
<shape android:shape="rectangle">
<solid android:color="@color/red"/>
</shape>
</inset>
在控件中使用这个insetDrawable
<ImageView
android:id="@+id/my_tv_3"
android:layout_width="100dp"
android:layout_height="100dp"
android:layout_marginTop="@dimen/dp16"
android:layout_marginLeft="@dimen/dp16"
android:foreground="@drawable/inset_drawable"
android:background="@drawable/wb"/>
ScaleDrawable在xml文件中的配置:
<scale xmlns:android="http://schemas.android.com/apk/res/android"
android:drawable="@drawable/具体资源名称"
android:scaleGravity=["top"|"bottom"|"left"|"right"|"center_vertical"
|"fill_vertical"|"center_horizontal"|"fill_horizontal"
|"center"|"fill"|"clip_vertical"|"clip_horizontal"]
android:scaleHeight="percentage"
android:scaleWidth="percentage"/>
scaleGrivity属性值的含义和grivity的属性值含义相同
scaleHeight 取值是个百分比,如果填写 80%,表示高度缩小到原来高度的20%
scaleWidth 取值是个百分比,如果填写 80%,表示宽度缩小到原来高度的20%
使用示例:
<scale xmlns:android="http://schemas.android.com/apk/res/android"
android:drawable="@drawable/p4"
android:scaleGravity="center"
android:scaleHeight="80%"
android:scaleWidth="80%"/>
仅仅这样配置好xml文件还不够,还要给drawable设置level,并且level的值必须要大于0,当levele取值是10000时,表示不进行缩放。在布局文件中使用scale_drawable.xml文件
<TextView
android:id="@+id/my_tv_4"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@drawable/scale_drawable"/>
在代码中设置drawable的level
val drawable = my_tv_4.background
drawable.setLevel(1)
ClipDrawable在xml文件中的配置:
<?xml version="1.0" encoding="utf-8"?>
<clip xmlns:android="http://schemas.android.com/apk/res/android"
android:drawable="@drawable/具体资源名称"
android:clipOrientation=["horizontal"|"vertical"]
android:gravity=["top"|"bottom"|"left"|"right"|"center_vertical"
|"fill_vertical"|"center_horizontal"|"fill_horizontal"
|"center"|"fill"|"clip_vertical"|"clip_horizontal"]>
</clip>
clipOrientation 取值horizontal 时表示从水平方向裁剪,取值 vertical 时表示从竖直方向裁剪
gravity属性的取值含义见下表:
将drawable放到容器的底部,不改变它的大小,在水平方向裁剪,示例:
<?xml version="1.0" encoding="utf-8"?>
<clip xmlns:android="http://schemas.android.com/apk/res/android"
android:drawable="@drawable/p6"
android:clipOrientation="horizontal"
android:gravity="bottom">
</clip>
将clip_drawable.xml文件使用到布局文件中
<TextView
android:id="@+id/my_tv_5"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@drawable/clip_drawable"/>
仅仅在布局文件中使用,还不够,还要设置ClipDrawable的等级
val drawable_clip = my_tv_5.background
//level的最大取值是10000,这里设置8000,表示裁剪2000,如果设置为0,表示完全裁剪,
//等级 设置为10000表示不裁剪。等级越大,表示裁剪的区域越小。
drawable_clip.setLevel(8000)
AnimationDrawable在xml文件中的配置
一个包含五帧的AnimationDrawable,帧间隔为300毫秒的动画的配置信息如下:
<?xml version="1.0" encoding="utf-8"?>
<animation-list xmlns:android="http://schemas.android.com/apk/res/android"
android:oneshot="false"
>
<item
android:drawable="@drawable/ic_sentiment_dissatisfied_black_24dp"
android:duration="300"
/>
<item
android:drawable="@drawable/ic_sentiment_neutral_black_24dp"
android:duration="300"
/>
<item
android:drawable="@drawable/ic_sentiment_satisfied_black_24dp"
android:duration="300"
/>
<item
android:drawable="@drawable/ic_sentiment_very_dissatisfied_black_24dp"
android:duration="300"
/>
</animation-list>
更多的标签的使用,大家可以去参考这篇文章
Android各种Drawable讲解和demo实例
https://blog.youkuaiyun.com/qq_29989087/article/details/81103524