Drawable介绍
Android中Drawable表示可以在Cances上进行绘制,和View不同的是,Drawable不会像View一样,对用户的的交互作出反馈。
Drawable可以是图片,同时也可以是xml,也可以使用代码构建具体的Drawable,非图片类型的Drawable也会占用更少的存储空间。
Drawable有很多的子类,比如BitmapDrawable,GradientDrawable,hapeDrawable,LayerDrawable:
BitmapDrawable
BitmapDrawable看名字,Drawable中带有一个图片,实际开发中可以使用代码去创建BitmapDrawable对象,同时也可以使用xml创建对应的BitmapDrawable。
<?xml version="1.0" encoding="utf-8"?>
<bitmap xmlns:android="http://schemas.android.com/apk/res/android"
android:src="@color/black"
android:antialias="true">
</bitmap>
更多的属性设置可以颠倒bitmap标签中去看,这样我们在xml中就将BitmapDrawable所需要的属性就设置好了。
ShapeDrawable
使用ShapeDrawable时,xml中可以使用shape(是GradientDrawable类)标签实现相应的图像:
<?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>
链接:Drawable-resource写法
具体的每一个标签里面的属性使用可以参考官网里面的介绍。
- <corners/> 用来设置四个角的圆角弧度,用px来表示
- <gradient/> 用来表示渐变效果,这个标签与solid是相互排斥的,solid表示纯色的效果
- <solid/> 标签,用来定义纯色,
- <padding/> 用来定义view中内容的位置,而不是给shape增加padding。((this pads the position of the View content, not the shape)
- <stroke/> 用来设置Shape的描边
LayerDrawable
LayerDrawable对应的是<layer-list/> 标签,它表示一种层次化的Drawable集合,<item/>作为每一层的元素,item中直接使用已有的drawable,同时也可以通过shape自定义新的drawable。
使用layer-list实现叠加效果的布局:
<?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="256dp">
<shape android:shape="rectangle">
<solid android:color="#ffffff" />
</shape>
</item>
<item
android:bottom="100dp"
android:left="100dp"
android:right="100dp">
<shape android:shape="rectangle">
<solid android:color="#BD1717" />
</shape>
</item>
</layer-list>
StateListDrawable
StateListDrawable对应于<selector>标签,selector标签中每一个item对应一种状态下的drawable样式
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android"
android:constantSize="false">
<item
android:state_pressed="false"
android:drawable="@drawable/shape_drawable">
</item>
<item
android:state_pressed="true"
android:drawable="@drawable/layer_drawable">
</item>
</selector>
将上面的这个drawable设置为Button的背景,按下和抬起的时候都是有着不同的效果
对于焦点类控件,例如EditText,可以设置state_focused,对于按钮类控件,例如Button,设置state_pressed,同时也还有许多其它状态属性
自定义Drawable
Drawable不会对用户的交互做出反应,因此自定义Drawable核心就是重写View的Draw方法,
public class RoundedDrawable extends Drawable {
private final Paint mPaint;
private final Bitmap mBitmap;
private RectF mRectF;
public RoundedDrawable(Bitmap bitmap) {
mPaint = new Paint();
mPaint.setAntiAlias(true);
mBitmap = bitmap;
//Shader used to draw a bitmap as a texture. The bitmap can be repeated or mirrored by setting the tiling mode.
BitmapShader shader = new BitmapShader(mBitmap, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP);
mPaint.setShader(shader);
}
@Override
public void draw(@NonNull Canvas canvas) {
canvas.drawRoundRect(mRectF, 60, 60, mPaint);
}
@Override
public void setAlpha(int i) {
mPaint.setAlpha(i);
}
@Override
public void setBounds(int left, int top, int right, int bottom) {
super.setBounds(left, top, right, bottom);
mRectF = new RectF(left, top, right, bottom);
}
@Override
public void setColorFilter(@Nullable ColorFilter colorFilter) {
mPaint.setColorFilter(colorFilter);
}
@Override
public int getOpacity() {
return PixelFormat.TRANSLUCENT;
}
// 缩放后的实际的大小
@Override
public int getIntrinsicHeight() {
//返回实际高度
return mBitmap.getHeight();
}
@Override
public int getIntrinsicWidth() {
return mBitmap.getWidth();
}
}
上面的代码,我们通过自定义drawable,在draw方法中可以将界面形状绘制成我们需要的形状。