kotlin 圓形進度條

kotlin版的自定義圓形進度條git

大多數啓動頁都會帶個進度條加載樣式,因此就本身用kotlin從新寫了一個,若是真的要很炫酷仍是有不少東西能夠附加的github

一個簡單的進度條基本組成就是一個背景環,一個進度環,須要注意的就是繪製的方式了canvas

由於圓形進度條是寬高對等的,咱們定義view寬高可能不是對等的,因此繪製的時候須要計算中間繪製,否則繪製的結果可能不是你理想的,好比下面右上角ide

 

 

 

固然,若是隻是兩個環,感受有點醜,不是很美觀,能夠添加一點元素讓它稍微的美觀一點,好比繪製一個進度百分比提示文字,圓環自定義顏色,中心在繪製一箇中心圓,這樣經過配置顏色要比兩個單調的圓環美觀許多字體

而後還能夠加入一點初始化或者結束的view動畫,這邊我加了一個進入縮放動畫,開始拿起鍵盤一把梭動畫

1.初始化spa

畫筆,配置顏色背景,字體,進度等都須要用到自定義屬性,因此初始化的時候須要把這些參數都實例化,而後剛纔加入的縮放動畫也是在初始化裏3d

在xml裏定義好stylecode

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <declare-styleable name="circleProgress">
        <attr name="circle_max" format="float" />
        <attr name="circle_progress" format="float" />
        <attr name="circle_width" format="dimension" />
        <attr name="circle_progress_color" format="color" />
        <attr name="circle_color" format="color" />
        <attr name="circle_text_color" format="color" />
        <attr name="circle_text_size" format="dimension" />
        <attr name="circle_text_isBold" format="boolean" />
        <attr name="circle_center_color" format="color" />
    </declare-styleable>
</resources>

而後編寫init方法orm

private fun init() {
        //自定義屬性
        val attributes: TypedArray = context.obtainStyledAttributes(
            attrs,
            R.styleable.circleProgress
        )
        mStrokeWidth = attributes.getDimension(R.styleable.circleProgress_circle_width, 1f)
        max = attributes.getFloat(R.styleable.circleProgress_circle_max, 100f)
        mProgress = attributes.getFloat(R.styleable.circleProgress_circle_progress, 0f)
        val bgColor = attributes.getColor(R.styleable.circleProgress_circle_color,Color.GRAY)
        val progressColor = attributes.getColor(R.styleable.circleProgress_circle_progress_color,Color.BLUE)
        val textColor = attributes.getColor(R.styleable.circleProgress_circle_text_color,Color.BLACK)
        val textSize = attributes.getDimension(R.styleable.circleProgress_circle_text_size,SizeUtils.dp2px(10f).toFloat())
        val isBold = attributes.getBoolean(R.styleable.circleProgress_circle_text_isBold,false)
        val centerColor = attributes.getColor(R.styleable.circleProgress_circle_center_color,Color.TRANSPARENT)
        attributes.recycle()
        //圓環畫筆
        bgPaint = Paint()
        bgPaint.style = Paint.Style.STROKE
        bgPaint.strokeWidth = mStrokeWidth
        bgPaint.color = bgColor
        bgPaint.isAntiAlias = true
        //中心圓畫筆
        centerPaint = Paint()
        centerPaint.style = Paint.Style.FILL
        centerPaint.color = centerColor
        centerPaint.isAntiAlias = true
        //進度條畫筆
        tintPaint = Paint()
        tintPaint.style = Paint.Style.STROKE
        tintPaint.strokeWidth = mStrokeWidth
        tintPaint.strokeCap = Paint.Cap.ROUND
        tintPaint.color = progressColor
        tintPaint.isAntiAlias = true
        //文字畫筆
        textPaint = Paint()
        textPaint.style = Paint.Style.FILL
        textPaint.textSize = textSize
        textPaint.textAlign = Paint.Align.CENTER
        textPaint.isFakeBoldText = isBold
        textPaint.color = textColor
        textPaint.isAntiAlias = true

        initAnimation()
    }
View Code

2.測量

由於寬高是不可控的,你不知道具體設置成什麼樣子,有的是寬高尺寸同樣,有的是寬大於高等,因此圓形直徑須要取最小值,這樣才能繪製成一個完整的圓形

override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec)
        mWidth = getRealSize(widthMeasureSpec)
        mHeight = getRealSize(heightMeasureSpec)
        /** 直徑 - 等寬高充滿 | 當寬高不一致時,取最小的畫圓 */
        val diameter = min(mWidth,mHeight)
        //半徑
        mRadius = diameter / 2f - mStrokeWidth
        /** 進度條繪製區域 */
        val mX = mWidth/2f-diameter/2
        val mY = mHeight/2f-diameter/2
        mRect = RectF(mX + mStrokeWidth, mY + mStrokeWidth, mX + diameter - mStrokeWidth, mY + diameter - mStrokeWidth)

        setMeasuredDimension(mWidth,mHeight)
    }

3.draw

圓形直接drawCircle繪製,進度條就須要繪製扇形了,而後經過傳過來的進度條,計算扇形的角度,百分比文字就是在圓形中心點繪製

override fun onDraw(canvas: Canvas?) {
        super.onDraw(canvas)
        val progress = mProgress / max * 360
        //繪製圓形
        canvas!!.drawCircle(mWidth / 2f, mHeight / 2f, mRadius, bgPaint)
        //繪製中心圓
        canvas.drawCircle(mWidth / 2f, mHeight / 2f, mRadius, centerPaint)
        //繪製進度
        canvas.drawArc(mRect, -90f, progress, false, tintPaint)
        //繪製文字(百分比)
        val percentage: Int = (mProgress / max * 100).toInt()
        val centerY = mHeight / 2 + mStrokeWidth / 2
        canvas.drawText("${percentage}%", mWidth / 2f, centerY, textPaint)
    }

就是這麼簡單,主要邏輯其實就在測量跟繪製

而後對外擴展設置進度,刷新視圖

 

使用:

binding.pbTime.setProgress(count)

這裏模擬一下加載進度,效果圖見最上方

 

github:https://github.com/1024477951/KotlinStrong

相關文章
相關標籤/搜索