绘制圆环进度

355 阅读2分钟

# 绘制圆环进度

实现该控件的姿势:

  • 自定义DrawView 继承 View
  • 绘制背景填充圆环
  • 绘制默认底色描边圆环
  • 绘制彩色进度描边圆环

发车 滴滴滴滴

# 创建DrawView.kt

class DrawView @JvmOverloads constructor(context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0) :
    View(context, attrs, defStyleAttr) {}

# 声明一些变量

 private val mContext: Context = context
    /**
     * 绘制默认圆环的画笔
     */
    private var paint: Paint? = null
    /**
     * 绘制圆环的画笔
     */
    private var cPaint: Paint? = null
    /**
     * 控件宽度
     */
    private var width: Float? = 0f
    /**
     * 控件高度
     */
    private var height: Float? = 0f
    /**
     * 绘制区域
     */
    private var rectF: RectF? = null

    /**
     * 背景颜色
     */
    private var defaultBackgroundColor: Int = Color.WHITE;

    /**
     * 默认不绘制
     */
    var isDrawBackgroundColor: Boolean = false

    /**
     * 默认圆环的颜色
     */
    private var annulusDefaultColor: Int = Color.parseColor("#d7d7d7")

    /**
     * 默认描边的宽度
     */
    private var strokeWidth: Float = 20f;
    /**
     * 绘制圆环的颜色
     */
    private var annulusDrawColor: Int = Color.GREEN

    /**
     * 绘制圆环的进度
     */
    var annulusProgress: Float = 0f

# 获取控件的宽高

 override fun onLayout(changed: Boolean, left: Int, top: Int, right: Int, bottom: Int) {
        super.onLayout(changed, left, top, right, bottom)
        width = measuredWidth.toFloat()
        height = measuredHeight.toFloat()
        if (width != null && height != null) {
            rectF = RectF(
                width!! / 2 - ((width!! / 2) - 30),
                30f,
                width!! / 2 + ((width!! / 2) - 30),
                height!! / 2 + ((height!! / 2) - 30)
            )
        }
    }

# 初始化 画笔

private fun initPaint() {
        paint = Paint()
        paint?.color = annulusDefaultColor
        paint?.isAntiAlias = true
        paint?.strokeWidth = strokeWidth
        paint?.style = Paint.Style.STROKE

        cPaint = Paint()
        cPaint?.color = annulusDrawColor
        cPaint?.isAntiAlias = true
        cPaint?.strokeWidth = strokeWidth
        cPaint?.style = Paint.Style.STROKE
        cPaint?.strokeCap = Paint.Cap.ROUND
        cPaint?.strokeJoin = Paint.Join.ROUND
    }

# 绘制

override fun onDraw(canvas: Canvas?) {
        super.onDraw(canvas)
        val drawWidth = width?.div(2)
        val drawHeight = height?.div(2)

        if (isDrawBackgroundColor) {
            canvas?.drawColor(Color.WHITE)
        } else {
            paint?.style = Paint.Style.FILL
            paint?.color = Color.WHITE
            paint?.let {
                drawWidth?.let { it1 ->
                    drawHeight?.let { it2 ->
                        canvas?.drawCircle(
                            it1,
                            it2,
                            it1.minus(30),
                            it
                        )
                    }
                }
            }
            paint?.color = annulusDefaultColor
            paint?.style = Paint.Style.STROKE
        }

        //绘制圆环
        paint?.let {
            drawWidth?.let { it1 ->
                drawHeight?.let { it2 ->
                    canvas?.drawCircle(
                        it1,
                        it2,
                        it1.minus(30),
                        it
                    )
                }
            }
        }

        //绘制彩色圆环
        if (annulusProgress > 0) {
            rectF?.let {
                cPaint?.let { it1 ->
                    canvas?.drawArc(
                        it,
                        270f,
                        annulusProgress,
                        false,
                        it1
                    )
                }
            }
        }
    }

# 声明 styleable 参数 供使用者配置

    <declare-styleable name="DrawView">
        <!--是否绘制背景颜色-->
        <attr name="is_draw_background" format="boolean"/>
        <!--画布背景颜色-->
        <attr name="canvas_background_color" format="color"/>
        <!--默认底色圆环的颜色-->
        <attr name="annulus_default_color" format="color"/>
        <!--绘制圆环的颜色-->
        <attr name="draw_annulus_color" format="color"/>
        <!--描边圆环的宽度-->
        <attr name="stroke_width" format="float"/>
    </declare-styleable>
 private fun initAttrs(attrs: AttributeSet?) {
        val typeArray: TypedArray = mContext.obtainStyledAttributes(attrs, R.styleable.DrawView)
        isDrawBackgroundColor = typeArray.getBoolean(R.styleable.DrawView_is_draw_background, isDrawBackgroundColor)
        defaultBackgroundColor =
            typeArray.getColor(R.styleable.DrawView_canvas_background_color, defaultBackgroundColor)
        annulusDefaultColor = typeArray.getColor(R.styleable.DrawView_annulus_default_color, annulusDefaultColor)
        annulusDrawColor = typeArray.getColor(R.styleable.DrawView_draw_annulus_color, annulusDrawColor)
        strokeWidth = typeArray.getFloat(R.styleable.DrawView_stroke_width, strokeWidth)
        typeArray.recycle()
    }

# 使用

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
        xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:tools="http://schemas.android.com/tools"
        xmlns:app="http://schemas.android.com/apk/res-auto"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        tools:context=".MainActivity">

    <com.joyssom.example.draw.DrawView
            android:id="@+id/draw_view"
            android:layout_centerInParent="true"
            android:layout_width="200dp"
            app:stroke_width="20"
            app:draw_annulus_color="@android:color/holo_green_light"
            app:canvas_background_color="@android:color/white"
            android:layout_height="200dp"/>

</RelativeLayout>
package com.joyssom.example

import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.os.Handler
import android.os.Message
import com.joyssom.example.draw.DrawView
import java.lang.ref.WeakReference

class MainActivity : AppCompatActivity() {
    private var drawView: DrawView? = null
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        drawView = findViewById(R.id.draw_view)
        //为了显示进度效果 加个handler 回调
        handler.sendEmptyMessageDelayed(0, 1000)
    }

    private val handler = MyHandler(this)

    companion object {
        class MyHandler(activity: MainActivity) : Handler() {
            private val weakReference: WeakReference<MainActivity> = WeakReference(activity)
            override fun handleMessage(msg: Message) {
                val activity = weakReference.get()
                when (msg.what) {
                    0 -> {
                        if (activity != null) {
                            if (activity.drawView?.annulusProgress!! < 200f) {
                                //每次添加 10f
                                activity.drawView?.annulusProgress = activity.drawView?.annulusProgress!! + 10f
                                //重绘
                                activity.drawView?.readDraw()
                                sendEmptyMessageDelayed(0, 1000)
                            } else {
                                removeMessages(0)
                            }
                        }
                    }
                }
            }
        }
    }
}