Android中Drawable的使用

  • Drawable简介
  • Drawable种类
  • 自定义Drawable

一.Drawble简介

1.简介

Drawable是个抽象类,是所有Drawable对象的基类.它表示是一种可以在Canvas上进行绘制的抽象的概念.比较常见的颜色和图片就是一个Drawable.

2.优点

它使用简单,比自定义View的成本低,并且非图片类型的Drawable占用空间较小

3.Drawable的宽高

Drawable可以通过getIntrinsicWidth和getIntrinsicHeight这两个方法获取内部宽高,但是并不是所有Drawble都有内部宽高,比如一张图片所形成的Drawble,它的内部宽高就是图片的宽高,而一个颜色所形成的Drawble,就没有内部宽高的概念.另外需要注意,Drawable的内部宽高不等同于它的大小,一般来说,Drawable没有大小的概念.

二.Drawable的种类

  • BitmapDrawable
  • NinePatchDrawable
  • ShapeDrawable
  • LayerDrawable
  • StateListDrawable
  • LevelListDrawable
  • TransitionDrawable
  • InsetDrawable
  • ScaleDrawable
  • ClipDrawable

1.BitmapDrawable

(1)用xml定义BitmapDrawable

表示一张图片,可以引用原始图片,也可以通过xml的方式来描述.下面是通过xml来表示一张图片。
// res/drawable/bitmapdrawable_test.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="false"//纹理映射,默认是false
    android:tileMode="disabled">//平铺模式,开启后gravity属性会被忽略
</bitmap>

android:gravity属性的可选值如下图所示:

在这里插入图片描述
android:tileMode属性可选值如下图所示:

在这里插入图片描述
具体效果如图:

在这里插入图片描述
(2)具体使用

	//xml中定义
    <ImageView
        android:id="@+id/image"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:background="@drawable/bitmapdrawable_test"></ImageView>

        //代码定义
        ImageView imageView = findViewById(R.id.image);
        //通过图片id获取bitmap
        Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.bitmapdrawable_test);
        BitmapDrawable bitmapDrawable = new BitmapDrawable(bitmap);
        bitmapDrawable.setAntiAlias(true);
        bitmapDrawable.setGravity(Gravity.RIGHT);
        bitmapDrawable.setTileModeXY(Shader.TileMode.MIRROR, Shader.TileMode.MIRROR);
        imageView.setImageDrawable(bitmapDrawable);
		//通过图片id获取drawable
        Drawable drawable = getResources().getDrawable(R.drawable.bitmapdrawable_test);
        imageView.setImageDrawable(drawable);
	

2.NinePatchDrawable

对应<nine-patch>标签,表示一张.9格式图片:

表示一张.9格式图片,可以直接引用图片,也可以用xml表示.
<?xml version="1.0" encoding="utf-8"?>
<nine-patch xmlns:android="http://schemas.android.com/apk/res/android"
    android:src="@drawable/ic_launcher_background"
    android:dither="true">
</nine-patch>

3.ShapeDrawable

对应<shape>标签,通过颜色来构造的图形,它既可以是纯色的图形,也可以是具有渐变效果的图形.

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
    android:shape="[ring | rectangle | oval | line]">//圆环/矩形/椭圆/横线
    <corners android:bottomLeftRadius="integer"//左下角的角度
             android:topLeftRadius="integer"//左上角
             android:topRightRadius="integer"//右上角
             android:bottomRightRadius="integer"//右下角
             android:radius="integer"/>//为四个角同时设定,优先级低
    <gradient android:angle="integer"//渐变效果,与solid互斥,angle表示渐变角度,默认为0,值是45的倍数,0表示从左到右,90表示从上到下
              android:centerX="integer"//渐变的中心点的x坐标
              android:centerY="integer//渐变的中心点的y坐标
              android:startColor="color"//渐变的起始色
              android:centerColor="color"//渐变中间色
              android:endColor="color"//渐变结束色
              android:gradientRadius="integer"//渐变半径,仅当type为radial时有效
              android:type="[radial | linear | sweep ]"//渐变类别(径向/线性/扫描线)
              android:useLevel="[true | false]"/>//一般为false,使用SateListDrawable时为true
    <padding android:bottom="integer"//表示与四周空白的距离
             android:left="integer"
             android:right="integer"
             android:top="integer"/>
    <size android:height="integer"//图形的固有大小,非最终大小
          android:width="integer"/>
    <solid android:color="color"/>//纯色填充
    <stroke android:color="color"//shape的描边
            android:width="integer"//描边的宽度
            android:dashGap="integer"//组成虚线的线段之间的间隔
            android:dashWidth="integer"/>//组成虚线的线段的宽度
</shape>

其中圆环额外的几个属性:

在这里插入图片描述
4.LayerDrawable

对应<layer-list>标签,表示一种层次化的Drawable集合

表示一种层次化的drawable集合.
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="@drawable/ic_launcher_background"
      android:id="@+id/layer"
      android:top="10dp"
      android:right="10dp"
      android:bottom="10dp"
      android:left="10dp"/>
</layer-list>
可以有多个item,下面的item会覆盖上面的item
<?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="@color/colorPrimary"/>
        </shape>
    </item>
    <item android:bottom="6dp">
        <shape android:shape="rectangle">
            <solid android:color="@color/colorAccent"/>
        </shape>
    </item>
    <item android:bottom="1dp"
        android:left="1dp"
        android:right="1dp">
        <shape android:shape="rectangle">
            <solid android:color="@color/colorAccent"/>
        </shape>
    </item>
</layer-list>

5.StateListDrawable

对应于<selector>标签,表示Drawable集合,每个Drawable都对应着View的一种状态,这样系统会根据View的状态来选择合适的Drawable,主要用于设置可点击的View的背景.

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android"
    android:constantSize="false"//固有大小是否随着状态的改变而改变,默认false,会改变,true不会改变,是固定值,内部所有Drawable的固有大小中的最大值
    android:dither="false"//是否开启抖动效果
    android:variablePadding="false">//padding是否随状态的改变而改变,默认false,不会改变,是固定值,内部所有Drawable的padding的最大值
    <item android:state_pressed="true"
          android:drawable="@drawable/xxx"/>
    <item android:state_focused="true"
          android:drawable="@drawable/xxx"/>
    <item android:drawable="@drawable/xxx"/>
</selector>

表示各种状态的属性:

在这里插入图片描述
6.LevelListDrawable

对应于<level-list>标签,表示一个Drawable集合,集合中的每个Drawable都有一个等级的概念,根据不同的等级,LevelListDrawable会切换为对应的Drawable.等级范围是0-1000,0是最小等级,也是默认值.

<?xml version="1.0" encoding="utf-8"?>
<level-list xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="@drawable/xxx"
      android:maxLevel="5"
      android:minLevel="1"/>
<item android:drawable="@drawable/xxx"
      android:minLevel="6"
      android:maxLevel="9"/>
</level-list>
//需要在代码中调用setLevel()方法,若作为ImageView背景,需调用setImageLevel()方法
//当某item的minLevel和maxLevel之间的数值 等于 setLevel所设置的数值时就会被加载。若都没有匹配的则都不显示

7.TransitionDrawable

对应<transition>标签,用于实现两个Drawable之间的淡入淡出效果.

<?xml version="1.0" encoding="utf-8"?>
<transition xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="@drawable/drawable1"/>
<item android:drawable="@drawable/drawable2"/>
</transition>

<TextView
    android:id="@+id/tv"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:background="@drawable/transition"/>

TextView textView = findViewById(R.id.tv);
TransitionDrawable transitionDrawable = (TransitionDrawable) textView.getBackground();
transitionDrawable.startTransition(1000);
//反向切换
//transitionDrawable.reverseTransition(1000);

8.InsetDrawable

对应<inset>标签,它可以将其它Drawable内嵌到自己当中,并可以在四周留出一定的距离.当一个View希望自己的背景比自己的实际区域小的时候,可以用InsetDrawable来实现.

<?xml version="1.0" encoding="utf-8"?>
<inset xmlns:android="http://schemas.android.com/apk/res/android"
    android:insetTop="15dp"
    android:insetBottom="15dp"
    android:insetLeft="15dp"
    android:insetRight="15dp">
    <shape android:shape="rectangle">
        <solid android:color="@color/colorAccent"/>
    </shape>
</inset>

9.ScaleDrawable

对应于<scale>标签,它可以根据自己的等级将指定的Drawable缩放到一定比例.

<?xml version="1.0" encoding="utf-8"?>
<scale xmlns:android="http://schemas.android.com/apk/res/android"
    android:drawable="@drawable/ic_launcher_background"
    android:scaleGravity="center"
    android:scaleHeight="75%"
    android:scaleWidth="75%">//比例越大,内部drawable看起来越小
</scale>
TextView textView = findViewById(R.id.tv);
ScaleDrawable scaleDrawable = (ScaleDrawable) textView.getBackground();
scaleDrawable.setLevel(1);
//level取值范围0到10000,但不能为0.

10.ClipDrawable

对应<clip>标签,它可以根据自己当前的等级来裁剪另一个Drawable,裁剪的方向可以通过clipOrientation和gravity这两个属性来共同控制.

<?xml version="1.0" encoding="utf-8"?>
<clip xmlns:android="http://schemas.android.com/apk/res/android"
    android:drawable="@drawable/ic_launcher_background"
    android:clipOrientation="vertical"//裁剪的方向
    android:gravity="bottom">//drawable放在容器中的位置
</clip>
ImageView imageView = findViewById(R.id.img);
ClipDrawable clipDrawable = (ClipDrawable) imageView.getDrawable();
clipDrawable.setLevel(8000);
//等级范围是0到10000,0表示完全裁剪,不可见,10000表示不裁剪,等级越大,表示裁剪的区域越小,上面代码表示顶部裁剪了20%的区域.

gravity属性的可选值有:

在这里插入图片描述
三.自定义Drawable

//它的主要功能,一个是作为ImageView中的图像来显示,一个是作为View的背景
//其工作原理,核心是draw()方法.
//自定义一个圆形的Drawable,它的半径会随着view的变化而变化.
public class CustomDrawable extends Drawable {
    
    private final Paint mPaint;
    
    public CustomDrawable(int color) {
        mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
        mPaint.setColor(color);
    }
    @Override
    public void draw(@androidx.annotation.NonNull Canvas canvas) {
        Rect bounds = getBounds();
        float cx = bounds.exactCenterX();
        float cy = bounds.exactCenterY();
        canvas.drawCircle(cx,cy,Math.min(cx,cy),mPaint);
        
    }
    
    @Override
    public void setAlpha(int alpha) {
        mPaint.setAlpha(alpha);
        invalidateSelf();
    }
    
    @Override
    public void setColorFilter(@androidx.annotation.Nullable ColorFilter colorFilter) {
        mPaint.setColorFilter(colorFilter);
        invalidateSelf();
    }
    
    @Override
    public int getOpacity() {
        return PixelFormat.TRANSLUCENT;
    }
}
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值