Android自定义播放按钮,外圈实现播放进度效果

在这里插入图片描述
大概样子就是这个样的,动图太麻烦就不弄了,直接上代码(注:代码里控件的大小都是写死的定值,没弄成xml中可以设置的,需要设置的朋友自己麻烦搞下吧)


```java
class PlayView : View {
    private lateinit var bgPaint: Paint//背景
    private lateinit var statusPaint: Paint//按钮状态
    private lateinit var progressPaint: Paint//播放进度
    private lateinit var totalPaint: Paint//外圈圆环

    private val radius = 32F//内圆
    private val bigRadius = 36F//外圆

    private var progress = 0//播放进度
    private var status = STOP_STATUS//播放状态

    private var path = Path()

    companion object {
        const val PLAY_STATUS = 0//播放
        const val STOP_STATUS = 1//暂停
    }

    constructor(context: Context) : super(context) {
        init(context)
    }

    constructor(context: Context, attributeSet: AttributeSet) : super(context, attributeSet) {
        init(context)
    }

    constructor(context: Context, attributeSet: AttributeSet, defStyleAttr: Int) : super(
        context,
        attributeSet,
        defStyleAttr
    ) {
        init(context)
    }

    override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec)

    }

    override fun onDraw(canvas: Canvas?) {
        super.onDraw(canvas)
        var viewWidth = right - left
        var viewHeight = bottom - top
        var centerX = viewWidth / 2
        var centerY = viewHeight / 2
        //先画最外圈的灰色的圆
        canvas?.drawCircle(centerX.toFloat(), centerY.toFloat(), bigRadius, totalPaint)
        //画进度扇形
        var rect = RectF(
            centerX - bigRadius,
            centerY - bigRadius,
            centerX + bigRadius,
            centerY + bigRadius
        )
        canvas?.drawArc(rect, 0F, (360 * progress / 100).toFloat(), true, progressPaint)
        //画按钮背景
        canvas?.drawCircle(centerX.toFloat(), centerY.toFloat(), radius, bgPaint)
        //画播放状态
        when (status) {
            STOP_STATUS -> {
                //画三角形
                path.reset()
                path.moveTo((centerX + 18).toFloat(), centerY.toFloat())
                path.lineTo((centerX - 9).toFloat(), (centerY - 15).toFloat())
                path.lineTo((centerX - 9).toFloat(), (centerY + 15).toFloat())
                path.close()
                canvas?.drawPath(path, statusPaint)
            }
            PLAY_STATUS -> {
                //画双竖杠
                canvas?.drawLine(
                    (centerX - 9).toFloat(), (centerY - 13).toFloat(),
                    (centerX - 9).toFloat(), (centerY + 13).toFloat(), statusPaint
                )
                canvas?.drawLine(
                    (centerX + 9).toFloat(), (centerY - 13).toFloat(),
                    (centerX + 9).toFloat(), (centerY + 13).toFloat(), statusPaint
                )
            }
        }
    }

    private fun init(context: Context) {
        totalPaint = Paint()
        totalPaint.color = context.resources.getColor(R.color.read_status_color)
        progressPaint = Paint()
        progressPaint.color = context.resources.getColor(R.color.colorAccent)
        bgPaint = Paint()
        bgPaint.color = context.resources.getColor(R.color.white)
        statusPaint = Paint()
        statusPaint.color = context.resources.getColor(R.color.colorAccent)
        statusPaint.strokeWidth = 4F
        path.fillType = Path.FillType.WINDING
    }

    fun setProgress(progress: Int) {
        this.progress = progress
        invalidate()
    }

    fun setStatus(status: Int) {
        this.status = status
        invalidate()
    }

    fun getStatus() = status

    fun reset() {
        this.status = STOP_STATUS
        this.progress = 0
        invalidate()
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值