按照官方的定义:可以用来绘制的东西都可以叫做Drawable
分类
BitmapDrawable、NinePatchDrawable
对应的标签时<bitmap>、<nine-patch>
- 它们所表示的其实就是一张图片,可以通过xml来定义(放在drawable文件夹下面的),也可以直接通过java代码来定义(传入一个bitmap对象)
ShapeDrawable
对应的标签是<shape>
- 这个是平时我们用的比较多的一个Drawable,可以理解为通过颜色构造出来的图形,这个图形可以是纯色的也可以具有渐变效果
- ShapeDrawable有四个类型:rectangle、oval、line、ring
可以绘制虚线、用虚线描边 - ShapeDrawable 可以设置size属性,指定shape的宽、高,但是这个表示的是固有的宽高,如果将它设置为view的背景的话,它会自适应view的宽高
- 啥是shape的固有宽高呢?(就是getIntrinsicWidth()、getIntrinsicHeight()获取到的)比如说对于上面讲的BitmapDrawable来说,这两个值得到的就是图片的原始大小,对于ShapeDrawable来说就是size属性的值
LayerDrawable
对应的标签是<layer-list>
- layer-list中可以包含多个item,每个item都是一个Drawable,在item中可以通过android:top、android:bottom、android:left、android:right来控制该Drawable相对于view的上下左右的偏移量
- 通过对item的位置的合理控制可以实现分层、叠加效果,比如说阴影的实现
StateListDrawable
对应的标签是<selector>
- 这个标签我们平时用的也比较多,表示的是view的状态,每个item都是一个Drawable,对应view的一种状态,比如说被按下、被选择、获取到了焦点、失去焦点等等
- StateListDrawable的固有大小会随着view的状态的改变而改变的,因为里面的item会切换,而每个item对应的Drawable的固有大小可以是不相同的,但是我们可以设置让StateListDrawable的固有大小保持不变(通过设置constantSize的值为true),这时候StateListDrawable的固有大小是所有item固有大小的最大值
LevelListDrawable
对应的标签是<level-list>
- 有多个item,每个item对应一个Drawable,但是每个item可以设置level
android:maxLevel="10"
android:minLevel="1"
我们可以通过Drawable的setLevel()方法来改变Drawable的level,这样的话,LevelListDrawable就会选择对应的item来显示
- Drawable的范围是0到10000,0是默认值
TransitionDrawable
对应于<transition>标签
- 用于实现两个Drawable之间的过渡效果
InsetDrawable
对应的标签是<inset>
- 可以将其他Drawable内嵌到自己当中并在四周留出一定的间距,当一个view希望自己的背景比自己的实际区域小的时候,可以采用InsetDrawable来实现
自定义Drawable
public class CustomerDrawable extends Drawable {
Paint paint;
Context context;
public CustomerDrawable(Paint paint, Context context) {
this.paint = new Paint(Paint.ANTI_ALIAS_FLAG);
this.paint.setColor(Color.parseColor("#ff0000"));
this.context=context;
bitmap=BitmapFactory.decodeResource(context.getResources(),R.drawable.ic_fish_0);
}
@Override
public void draw(@NonNull Canvas canvas) {
//绘制纯色背景
// Rect rect=getBounds();
// canvas.drawCircle(rect.exactCenterX(),rect.exactCenterY(),Math.min(rect.exactCenterX(),rect.exactCenterY()),paint);
//绘制图片背景
canvas.drawBitmap(bitmap,0,0,null);
}
Bitmap bitmap;
@Override
public void setAlpha(int alpha) {
}
@Override
public void setColorFilter(@Nullable ColorFilter colorFilter) {
}
@Override
public int getOpacity() {
return PixelFormat.TRANSLUCENT;
}
@Override
public int getIntrinsicWidth() {
if(bitmap!=null)
{
return bitmap.getWidth();
}
return super.getIntrinsicWidth();
}
@Override
public int getIntrinsicHeight() {
if(bitmap!= null)
{
return bitmap.getHeight();
}
return super.getIntrinsicHeight();
}
- 这几个方法都是必须实现的,注意Drawable的getBounds方法,可以得到Drawable的实际区域的大小
网友评论