Android 的 Drawable 表示的是一种可以在 Canvas 上进行绘制抽象的概念,是一个抽象类,是所有 Drawable 对象的基类,每个具体的 Drawable 都是它的子类。
Drawable 的分类
- BitmapDrawable ,它表示的是一张图片,可以通过 XML 描述。
<?xml version="1.0" encoding="utf-8"?>
<bitmap xmlns:android="http://schemas.android.com/apk/res/android"
android:src="@drawable/ic_launcher_background" 图片资源的id
android:antialias="true" 是否开启图片抗锯齿功能,会降低图片清晰度,幅度较低可以忽略
android:dither="true" 是否开启抖动效果,可以让高质量的图片在低质量的屏幕上保持较好显示效果
android:filter="true" 是否开启过滤效果,图片被拉伸或压缩会保持较好的显示效果
android:gravity="center" 对图片进行定位,可以用 “|” 来组合使用
android:mipMap="true" 纹理映像,开发不常用
android:tileMode="disabled" 平铺模式,disabled 关闭平铺模式,repeat 水平和竖直方向上平铺,mirror 水平和竖直方向上投影效果,clamp 四周像素向周围拓展
>
</bitmap>
- ShapeDrawable ,是一种常见的 Drawable,可以理解为通过颜色构造的图形,既可以是纯色的图形,也可以是渐变效果的图形。
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle"> 图形的形状,rectangle 矩形,oval 椭圆,line 横线,ring 圆环
<corners shape 的四个角的角度,圆角的程度,只试用于矩形 shape
android:radius="10dp" 四个角同时设定相同的角度,优先级较低,会被其他四个属性覆盖
android:topLeftRadius="5dp" 设定最上角角度
android:topRightRadius="5dp" 设定右上角角度
android:bottomLeftRadius="5dp" 设定最下角角度
android:bottomRightRadius="5dp"/> 设定右下角角度
<gradient 与<solid>标签互相排斥,表示渐变效果
android:angle="90" 渐变的角度,45倍数,0表示从左到右,90表示从下到上
android:centerX="45" 渐变的中心点的横坐标
android:centerY="45" 渐变的中心点的纵坐标
android:centerColor="#ff0000" 渐变的中心色
android:endColor="#00ff00" 渐变的结束颜色
android:gradientRadius="30dp" 渐变半径,仅当android:type="radial"有效
android:startColor="#0000ff" 渐变的开始颜色
android:type="linear" 渐变类别,linear默认线性渐变,radial 径向渐变,sweep扫描线渐变
android:useLevel="false"/> 一般为false,Drawable为StateListDrawable 使用时为true
<size shape 的大小,固有的宽高,作为 View 背景时,会变为 View 的大小
android:width="90dp"
android:height="45dp"/>
<solid 纯色填充
android:color="#000000"/>
<stroke shape 的描边
android:width="10dp" 描边的宽度,越大则 shape 的边缘线看起来越粗
android:color="#ff0000" 描边的颜色
android:dashWidth="5dp" 组成虚线线段的宽度
android:dashGap="5dp"/> 组成虚线的线段之间的间隔,间隔越大空隙越大
</shape>
- LayerDrawable 对应 XML 标签是,表示的是一种层次化的 Drawable 集合,将不同的 Drawable 放置不同的层次上达到叠加后的效果。
<?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>
<item
android:bottom="6dp">
<shape android:shape="rectangle">
<solid android:color="#ffffff"/>
</shape>
</item>
<item
android:bottom="1dp"
android:left="1dp"
android:right="1dp">
<shape android:shape="rectangle">
<solid android:color="#ffffff"/>
</shape>
</item>
</layer-list>
- StateListDrawable 对应于标签,表示 Drawable 集合,每个 Drawable 对应着 View 的一种状态,系统根据 View 的状态来选择合适的 Drawable,不添加状态表示默认显示状态。
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android"
android:constantSize="true" Drawable 的大小是否随状态的改变而改变,默认值为 false
android:dither="true" 是否开启抖动效果,图片在低质量屏幕上获得更好的显示效果
android:variablePadding="true"> Drawable 的 padding 是否随状态的改变而改变,默认值为 false
<item
android:drawable="@drawable/bitmap_drawable"
android:state_pressed="true" 表示按下状态,按下后没有松开时的状态
android:state_focused="true" 表示 View 已经获取了焦点
android:state_hovered="true" 表示是否有光标移动到组件上
android:state_selected="true" 表示用户选择了 View
android:state_checkable="true" 表示是否可以被点击
android:state_checked="true" 表示用户选中了 View,试用于 CheckBox 类选中非选中 View
android:state_enabled="true" 表示 View 当前处于可用状态
android:state_activated="true" 表示当前控件是否被激活
android:state_window_focused="true"/> 表示当前界面是否得到焦点
</selector>
- LevelListDrawable 对应于标签,表示一个 Drawable 集合,集合中的每个 Drawable 都有一个等级的概念,根据不同的等级会切换对应的 Drawable,可通过 setImageLevel 方法进行设置。
<?xml version="1.0" encoding="utf-8"?>
<level-list xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="@mipmap/ic_launcher"
android:maxLevel="0"/>
<item android:drawable="@mipmap/ic_launcher"
android:minLevel="1"/>
</level-list>
- TransitionDrawable 对应于标签,它用于实现 Drawable 之间的淡入淡出效果。
<?xml version="1.0" encoding="utf-8"?>
<transition xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:drawable="@drawable/shape_drawable"
android:top="10dp"
android:right="10dp"
android:bottom="10dp"
android:left="10dp"/>
<item
android:drawable="@mipmap/ic_launcher"
android:top="10dp"
android:right="10dp"
android:bottom="10dp"
android:left="10dp"/>
</transition>
代码设置效果
TransitionDrawable drawable = (TransitionDrawable) textView.getBackground();
drawable.startTransition(5000); 正向过渡
drawable.reverseTransition(5000); 反向过渡
- InsetDrawable 对应于标签,他可以将其他 Drawable 内嵌到自己当中,并可以在四周留出一点的间距。
<?xml version="1.0" encoding="utf-8"?>
<inset xmlns:android="http://schemas.android.com/apk/res/android"
android:insetLeft="10dp"
android:insetTop="10dp"
android:insetRight="10dp"
android:insetBottom="10dp"
>
<shape android:shape="rectangle">
<solid android:color="#ff0000"/>
</shape>
</inset>
- ScaleDrawable 对应于标签,它可以根据自己的等级将指定的 Drawable 缩放到一定比例。
<?xml version="1.0" encoding="utf-8"?>
<scale xmlns:android="http://schemas.android.com/apk/res/android"
android:drawable="@drawable/shape_drawable"
android:scaleGravity="center"
android:scaleHeight="50%" 缩放高,值越大高越小
android:scaleWidth="50%"> 缩放宽,值越大宽越小
</scale>
代码设置等级
ScaleDrawable scaleDrawable = (ScaleDrawable) view.getBackground();
scaleDrawable.setLevel(1); //如果设置为0表示不可见
- ClipDrawable 对应于标签,可以根据当前的等级来裁剪另一个 Drawable。
<?xml version="1.0" encoding="utf-8"?>
<clip xmlns:android="http://schemas.android.com/apk/res/android"
android:drawable="@drawable/shape_drawable"
android:clipOrientation="vertical" 设置裁剪方向
android:gravity="bottom"> 从顶部开始裁剪
</clip>
代码设置裁剪范围
ImageView clip = findViewById(R.id.iv_clip);
ClipDrawable clipDrawable = (ClipDrawable) clip.getBackground();
clipDrawable.setLevel(8000); //裁剪20%,值为0 - 10000,值越大裁剪越少
- 自定义 Drawable ,示例代码
public class CustomDrawable extends Drawable {
private final Paint paint;
public CustomDrawable(int color) {
paint = new Paint(Paint.ANTI_ALIAS_FLAG);
paint.setColor(color);
}
@Override
public void draw(@NonNull Canvas canvas) {
Rect r = getBounds(); //获取实际的大小
float centerX = r.exactCenterX();
float exactCenterY = r.exactCenterY();
canvas.drawCircle(centerX,exactCenterY,Math.min(centerX,exactCenterY),paint);
}
@Override
public void setAlpha(int alpha) {
paint.setAlpha(alpha);
invalidateSelf();
}
@Override
public void setColorFilter(@Nullable ColorFilter colorFilter) {
paint.setColorFilter(colorFilter);
invalidateSelf();
}
@Override
public int getOpacity() {
return PixelFormat.TRANSLUCENT;
}
}
代码设置
ImageView imageview= findViewById(R.id.custom_drawable);
CustomDrawable drawable = new CustomDrawable(Color.RED);
imageview.setBackgroundDrawable(drawable);