Android Drawable总结

Android Drawable总结

概述

Drawable有很多种,它们都表示一种图像的概念,但是它们又不全是图片,通过颜色也可以构造出各式各样的图像的效果。在实际开发中,Drawable常被用来作为View的背景使用。Drawable一般都是通过XML来定义的,当然我们也可以通过代码来创建具体的Drawable对象,只是用代码创建会稍显复杂。在Android的设计中,Drawable是一个抽象类,它是所有Drawable对象的基类。

在这里插入图片描述

BitmapDrawable 位图图像

在这里插入图片描述

XML实现

基本属性

<bitmap>:根元素
    - src:资源文件
    - antialias:是否抗锯齿
	- gravity:当图片小雨容器尺寸时,图片的位置设置
    - tileMode:平铺模式

定义XML位图

<bitmap xmlns:android="http://schemas.android.com/apk/res/android"
    android:antialias="true"
    android:gravity="fill"
    android:src="@drawable/apple_pic"
    android:tileMode="disabled" />

使用XML位图

val bitmapDrawable = ContextCompat.getDrawable(mContext, R.drawable.bitmap_drawable)
iv1.setImageDrawable(bitmapDrawable)

代码实现

val bitmap = BitmapFactory.decodeResource(resources, R.drawable.apple_pic)
val bitmapDrawable2 = BitmapDrawable(resources, bitmap)
iv2.setImageDrawable(bitmapDrawable2)

LayerDrawable

图层图像。

在这里插入图片描述

XML实现

基本属性

<layer-list>:根元素
<item>:子元素
	- drawable:图片资源
	- top:顶部偏移
	- right:右边偏移
	- bottom:底部偏移
	- left:左边偏移

定义XML图层

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

    <item
          android:bottom="10dp"
          android:left="10dp"
          android:right="10dp"
          android:top="10dp">
        <shape android:shape="rectangle">
            <solid android:color="#FF0000" />
        </shape>
    </item>

    <item
          android:bottom="20dp"
          android:left="20dp"
          android:right="20dp"
          android:top="20dp">
        <shape android:shape="oval">
            <solid android:color="#00FF00" />
        </shape>
    </item>

    <item android:gravity="center">
        <shape android:shape="oval">
            <size
                  android:width="50dp"
                  android:height="50dp" />
            <stroke
                    android:width="5dp"
                    android:color="#0000FF" />
        </shape>
    </item>
</layer-list>

使用XML图层

val layerDrawable = ContextCompat.getDrawable(mContext, R.drawable.layer_drawable)
iv1.setImageDrawable(layerDrawable)

代码实现

val drawable = ContextCompat.getDrawable(mContext, R.drawable.a)
val rectDrawable = GradientDrawable().apply {
    shape = GradientDrawable.RECTANGLE
    setColor(Color.parseColor("#FF0000"))
}
val ovalDrawable = GradientDrawable().apply {
    shape = GradientDrawable.OVAL
    setColor(Color.parseColor("#00FF00"))
}
val ringDrawable = GradientDrawable().apply {
    setSize(50.dp, 50.dp)
    shape = GradientDrawable.OVAL
    setStroke(5.dp, Color.parseColor("#0000FF"))
}
val arr = arrayOf(drawable, rectDrawable, ovalDrawable, ringDrawable)
val layerDrawable2 = LayerDrawable(arr).apply {
    setLayerInset(1, 10.dp, 10.dp, 10.dp, 10.dp)
    setLayerInset(2, 20.dp, 20.dp, 20.dp, 20.dp)
    setLayerGravity(3, Gravity.CENTER)
}
iv2.setImageDrawable(layerDrawable2)

StateListDrawable

状态列表图像。

XML实现

基本属性

<selector>:根元素
<item>:子元素
	- drawable:图片资源
	- state_pressed:是否按下
	- state_checked:是否选中
	- state_enabled:是否可用

定义XML

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:drawable="@drawable/a" android:state_pressed="true" />
    <item android:drawable="@drawable/b" />
</selector>

使用

val stateListDrawable = ContextCompat.getDrawable(mContext, R.drawable.state_list_drawable)
iv1.setImageDrawable(stateListDrawable)

代码实现

val stateListDrawable2 = StateListDrawable().apply {
    addState(
        intArrayOf(android.R.attr.state_pressed),
        ContextCompat.getDrawable(mContext, R.drawable.a)
    )
    addState(StateSet.NOTHING, ContextCompat.getDrawable(mContext, R.drawable.b))
}
iv2.setImageDrawable(stateListDrawable2)

LevelListDrawable

级别列表图像。

在这里插入图片描述

XML实现

基本属性

<level-list>:根元素
<item>:子元素
	- drawable:图片资源
	- maxLevel:item的最高级别
	- minLevel:item的最低级别

定义XML图像

<?xml version="1.0" encoding="utf-8"?>
<level-list xmlns:android="http://schemas.android.com/apk/res/android">
    <item
        android:drawable="@drawable/a"
        android:maxLevel="1" />
    <item
        android:drawable="@drawable/b"
        android:maxLevel="2" />
    <item
        android:drawable="@drawable/c"
        android:maxLevel="3" />
    <item
        android:drawable="@drawable/d"
        android:maxLevel="4" />
    <item
        android:drawable="@drawable/e"
        android:maxLevel="5" />
    <item
        android:drawable="@drawable/apple_pic"
        android:maxLevel="6" />
    <item
        android:drawable="@drawable/banana_pic"
        android:maxLevel="7" />
    <item
        android:drawable="@drawable/cherry_pic"
        android:maxLevel="8" />
    <item
        android:drawable="@drawable/grape_pic"
        android:maxLevel="9" />
    <item
        android:drawable="@drawable/mango_pic"
        android:maxLevel="10" />
</level-list>

使用

val levelListDrawable =
    ContextCompat.getDrawable(mContext, R.drawable.level_list_drawable)!!
iv1.setImageDrawable(levelListDrawable)

代码实现

val levelListDrawable2 = LevelListDrawable().apply {
    addLevel(0, 1, ContextCompat.getDrawable(mContext, R.drawable.a))
    addLevel(0, 2, ContextCompat.getDrawable(mContext, R.drawable.b))
    addLevel(0, 3, ContextCompat.getDrawable(mContext, R.drawable.c))
    addLevel(0, 4, ContextCompat.getDrawable(mContext, R.drawable.d))
    addLevel(0, 5, ContextCompat.getDrawable(mContext, R.drawable.e))
    addLevel(0, 6, ContextCompat.getDrawable(mContext, R.drawable.apple_pic))
    addLevel(0, 7, ContextCompat.getDrawable(mContext, R.drawable.banana_pic))
    addLevel(0, 8, ContextCompat.getDrawable(mContext, R.drawable.cherry_pic))
    addLevel(0, 9, ContextCompat.getDrawable(mContext, R.drawable.grape_pic))
    addLevel(0, 10, ContextCompat.getDrawable(mContext, R.drawable.mango_pic))
}
iv2.setImageDrawable(levelListDrawable2)
seekBar.setOnSeekBarChangeListener(object : SeekBar.OnSeekBarChangeListener {
    override fun onProgressChanged(seekBar: SeekBar?, progress: Int, fromUser: Boolean) {
        levelListDrawable.level = progress
        levelListDrawable2.level = progress
    }

    override fun onStartTrackingTouch(seekBar: SeekBar?) {
    }

    override fun onStopTrackingTouch(seekBar: SeekBar?) {
    }
})

TransitionDrawable

过渡图像。

在这里插入图片描述

XML实现

基本属性

<transition>:根元素
<item>:子元素
	- drawable:图片资源
	- top、bottom、left、right:偏移值

定义XML图像

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

使用

val transitionDrawable = ContextCompat.getDrawable(
    mContext, R.drawable.transition_drawable
) as TransitionDrawable
iv1.setImageDrawable(transitionDrawable)

代码实现

val drawables = arrayOf(
    ContextCompat.getDrawable(mContext, R.drawable.a),
    ContextCompat.getDrawable(mContext, R.drawable.b)
)
val transitionDrawable2 = TransitionDrawable(drawables)
iv2.setImageDrawable(transitionDrawable2)

InsetDrawable

插入可绘制图像。

在这里插入图片描述

XML实现

基本属性

<inset>:根元素
	- drawable:图片资源
	- insetLeft、insetTop、insetRight、insetBottom:插入图片距离边界距离

定义XML图像

<?xml version="1.0" encoding="utf-8"?>
<inset xmlns:android="http://schemas.android.com/apk/res/android"
    android:drawable="@drawable/a"
    android:insetLeft="200dp"
    android:insetTop="200dp" />

使用

val insetDrawable = ContextCompat.getDrawable(mContext, R.drawable.inset_drawable)
iv1.setImageDrawable(insetDrawable)

代码实现

val insetDrawable2 = InsetDrawable(
    ContextCompat.getDrawable(mContext, R.drawable.a),
    300.dp
)
iv2.setImageDrawable(insetDrawable2)

ClipDrawable

剪裁图像。

在这里插入图片描述

XML实现

基本属性

<clip>:根元素
	- drawable:图片资源
	- clipOrientation:剪裁方向
		- horizontal:水平方向
		- vertical:垂直放心
	- gravity:位置

定义XML图像

<?xml version="1.0" encoding="utf-8"?>
<clip xmlns:android="http://schemas.android.com/apk/res/android"
    android:clipOrientation="horizontal"
    android:drawable="@drawable/a"
    android:gravity="center" />

使用

 val clipDrawable = ContextCompat.getDrawable(mContext, R.drawable.clip_drawable)!!
iv1.setImageDrawable(clipDrawable)

代码实现

val clipDrawable2 = ClipDrawable(
    ContextCompat.getDrawable(mContext, R.drawable.a),
    Gravity.CENTER,
    ClipDrawable.VERTICAL
)
iv2.setImageDrawable(clipDrawable2)
seekBar.setOnSeekBarChangeListener(object : SeekBar.OnSeekBarChangeListener {
    override fun onProgressChanged(seekBar: SeekBar?, progress: Int, fromUser: Boolean) {
        clipDrawable.level = progress
        clipDrawable2.level = progress
    }

    override fun onStartTrackingTouch(seekBar: SeekBar?) {
    }

    override fun onStopTrackingTouch(seekBar: SeekBar?) {
    }
})

ScaleDrawable

缩放图像。

在这里插入图片描述

XML实现

基本属性

<scale>:根元素
	- drawable:图片资源
	- scaleHeight、scaleWidth:缩放比例
	- scaleGravity:图像缩放后的位置

定义XML图像

<?xml version="1.0" encoding="utf-8"?>
<scale xmlns:android="http://schemas.android.com/apk/res/android"
    android:drawable="@drawable/a"
    android:scaleWidth="100%"
    android:scaleHeight="100%"
    android:scaleGravity="center" />

使用

val scaleDrawable = ContextCompat.getDrawable(mContext, R.drawable.scale_drawable)!!
iv1.setImageDrawable(scaleDrawable)

代码实现

val scaleDrawable2 =
    ScaleDrawable(ContextCompat.getDrawable(mContext, R.drawable.a), Gravity.CENTER, 1F, 1F)
iv2.setImageDrawable(scaleDrawable2)
seekBar.setOnSeekBarChangeListener(object : SeekBar.OnSeekBarChangeListener {
    override fun onProgressChanged(seekBar: SeekBar?, progress: Int, fromUser: Boolean) {
        scaleDrawable.level = progress
        scaleDrawable2.level = progress
    }

    override fun onStartTrackingTouch(seekBar: SeekBar?) {
    }

    override fun onStopTrackingTouch(seekBar: SeekBar?) {
    }
})

ShapeDrawable

形状图像。

在这里插入图片描述

XML实现

基本属性

<shape>:根元素
	- shape:形状类型
		- rectangle:矩形
		- oval:椭圆
		- line:水平线
		- ring:换下
	<corner>:子元素,设置圆角
		- radius:所有角的圆角设置
		- topLeftRadius、topRightRadius、bottomLeftRadius、bottomRightRadius:单独角的圆角设置
	<padding>:子元素,设置内边距
	<size>:子元素,设置大小
		- height、width:设置宽高
	<solid>:填充颜色
		- color:填充颜色设置
	<stroke>:设置边框
		- width:边框宽度
		- color:边框颜色
		- dashGap:虚线间隔长度
		- dashWith:虚线长度

定义XML图像

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
    android:shape="rectangle">
    <corners android:radius="20dp" />
    <solid android:color="#0000FF" />
    <stroke
        android:width="5dp"
        android:color="#FF0000"
        android:dashWidth="10dp"
        android:dashGap="5dp" />
</shape>

使用

val shapeDrawable = ContextCompat.getDrawable(mContext, R.drawable.shape_drawable)
iv1.setImageDrawable(shapeDrawable)

GradientDrawable

渐变图像。

在这里插入图片描述

XML实现

基本属性

<shape>:根元素
<gradient>:子元素,表示渐变
	- startColor:开始颜色
	- centerColor:中间颜色
	- endColor:结束颜色
	- angle:角度,默认为0,从左向右
	- centerX、centerY:渐变中心点
	- type:渐变类型
		- radial:径向渐变
		- linear:线性渐变
		- sweep:流线渐变
	- gradientRadius:渐变半径,仅在type="radial"中使用

定义XML图像

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
    android:shape="oval">
    <gradient
        android:endColor="#BBFFFF"
        android:gradientRadius="50%p"
        android:startColor="#00F5FF"
        android:type="radial" />
</shape>

使用

val gradientDrawable = ContextCompat.getDrawable(mContext, R.drawable.gradient_drawable)
iv1.setImageDrawable(gradientDrawable)

代码实现

val gradientDrawable2 = GradientDrawable().apply {
    shape = GradientDrawable.OVAL
    gradientType = GradientDrawable.RADIAL_GRADIENT
    colors = intArrayOf(Color.parseColor("#00F5FF"), Color.parseColor("#BBFFFF"))
    gradientRadius = 100.dp.toFloat()
}
iv2.setImageDrawable(gradientDrawable2)

AnimationDrawable

动画图像。

在这里插入图片描述

XML实现

基本属性

<animation-list>:根元素
	- oneshot:是否只播放一次
<item>:子元素
	- drawable:图片资源
	- duration:每帧持续时间

定义XML图像

<?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/a"
        android:duration="500" />
    <item
        android:drawable="@drawable/b"
        android:duration="500" />
    <item
        android:drawable="@drawable/c"
        android:duration="500" />
    <item
        android:drawable="@drawable/d"
        android:duration="500" />
    <item
        android:drawable="@drawable/e"
        android:duration="500" />
    <item
        android:drawable="@drawable/apple_pic"
        android:duration="500" />
    <item
        android:drawable="@drawable/banana_pic"
        android:duration="500" />
    <item
        android:drawable="@drawable/cherry_pic"
        android:duration="500" />
    <item
        android:drawable="@drawable/mango_pic"
        android:duration="500" />
    <item
        android:drawable="@drawable/grape_pic"
        android:duration="500" />
</animation-list>

使用

val animationDrawable =
ContextCompat.getDrawable(mContext, R.drawable.animation_drawable) as AnimationDrawable
iv1.setImageDrawable(animationDrawable)

iv1.setOnClickListener {
    isStart1 = !isStart1
    if (isStart1) {
        animationDrawable.start()
    } else {
        if (animationDrawable.isRunning) animationDrawable.stop()
    }
}

代码实现

private val drawables = intArrayOf(
    R.drawable.a,
    R.drawable.b,
    R.drawable.c,
    R.drawable.d,
    R.drawable.e,
    R.drawable.apple_pic,
    R.drawable.banana_pic,
    R.drawable.cherry_pic,
    R.drawable.mango_pic,
    R.drawable.grape_pic,
)

val animationDrawable2 = AnimationDrawable().apply {
    drawables.forEachIndexed {
        index, item ->
        addFrame(ContextCompat.getDrawable(mContext, item)!!, 500)
    }
}
iv2.setImageDrawable(animationDrawable2)

iv2.setOnClickListener {
    isStart2 = !isStart2
    if (isStart2) {
        animationDrawable2.start()
    } else {
        if (animationDrawable2.isRunning) animationDrawable2.stop()
    }
}

自定义Drawable

class CustomDrawable:Drawable() {
    override fun draw(canvas: Canvas) {
        TODO("Not yet implemented")
    }

    override fun setAlpha(alpha: Int) {
        TODO("Not yet implemented")
    }

    override fun setColorFilter(colorFilter: ColorFilter?) {
        TODO("Not yet implemented")
    }

    override fun getOpacity(): Int {
        TODO("Not yet implemented")
    }
}
  • setAlpha():为Drawable指定alpha值,0表示完全透明,255表示不透明。
  • setColorFilter():颜色过滤器。
  • getOpacity():返回Drawable的透明度
    • PixelFormat.TRANSLUCENT:半透明的。
    • PixelFormat.TRANSPARENT:透明的。
    • PixelFormat.OPAQUE:不透明的。
    • PixelFormat.UNKNOWN:未知。
  • draw():绘制。

CustomCircleDrawable

定义一个旋转的进度条Drawable。

在这里插入图片描述

定义Drawable类

class CustomCircleDrawable : Drawable(), Animatable {

    val CIRCLE_WIDTH = 5.dp.toFloat()

    private val bgPaint = Paint(Paint.ANTI_ALIAS_FLAG).apply {
        style = Paint.Style.STROKE
        strokeWidth = CIRCLE_WIDTH
        color = Color.GRAY
    }

    private val progressPaint = Paint(Paint.ANTI_ALIAS_FLAG).apply {
        style = Paint.Style.STROKE
        strokeWidth = CIRCLE_WIDTH
        strokeCap = Paint.Cap.ROUND
        color = Color.RED
    }

    private var progress = 0F

    private val valueAnimator = ValueAnimator.ofFloat(0F, 1F).apply {
        duration = 3000L
        repeatCount = Animation.INFINITE
        interpolator = LinearInterpolator()
        addUpdateListener {
            //[0.0.~1.0]
            progress = it.animatedValue as Float
            invalidateSelf()
        }
    }

    init {
        start()
    }

    override fun draw(canvas: Canvas) {
        var radius = (min(bounds.width(), bounds.height()) / 2).toFloat()
        radius -= (bgPaint.strokeWidth / 2)
        val centerX = bounds.exactCenterX()
        val centerY = bounds.exactCenterY()
        val rectF = RectF().apply {
            left = centerX - radius
            right = centerX + radius
            top = centerY - radius
            bottom = centerY + radius
        }
        canvas.rotate(360F * progress, centerX, centerY)
        canvas.drawArc(rectF, 0F, 360F, false, bgPaint)
        canvas.drawArc(rectF, -90F, 360F * progress, false, progressPaint)
    }

    override fun setAlpha(alpha: Int) {
        bgPaint.alpha = alpha
        invalidateSelf()
    }

    override fun setColorFilter(colorFilter: ColorFilter?) {
        bgPaint.colorFilter = colorFilter
        invalidateSelf()
    }

    override fun getOpacity(): Int {
        return PixelFormat.OPAQUE
    }

    override fun start() {
        if (valueAnimator.isRunning) return
        valueAnimator.start()
    }

    override fun stop() {
        if (valueAnimator.isRunning) valueAnimator.cancel()
    }

    override fun isRunning(): Boolean {
        return valueAnimator.isRunning
    }
}

使用

val drawable = CustomCircleDrawable()
imageView.setImageDrawable(drawable)

imageView.setOnClickListener {
    if (!drawable.isRunning) {
        drawable.start()
    } else {
        drawable.stop()
    }
}

代码下载

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值