kotlin版的自定義圓形進度條

大多數啟動頁都會帶個進度條加載樣式,所以就自己用kotlin重新寫了一個,如果真的要很炫酷還是有很多東西可以附加的
一個簡單的進度潭訓本組成就是一個背景環,一個進度環,需要注意的就是繪制的方式了
因為圓形進度條是寬高對等的,我們定義view寬高可能不是對等的,所以繪制的時候需要計算中間繪制,不然繪制的結果可能不是你理想的,比如下面右上角

當然,如果只是兩個環,感覺有點丑,不是很美觀,可以添加一點元素讓它稍微的美觀一點,比如繪制一個進度百分比提示文字,圓環自定義顏色,中心在繪制一個中心圓,這樣通過配置顏色要比兩個單調的圓環美觀許多
然后還可以加入一點初始化或者結束的view影片,這邊我加了一個進入縮放影片,開始拿起鍵盤一把梭
1.初始化
畫筆,配置顏色背景,字體,進度等都需要用到自定義屬性,所以初始化的時候需要把這些引數都實體化,然后剛才加入的縮放影片也是在初始化里
在xml里定義好style
<?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方法
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
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/271203.html
標籤:其他
上一篇:iOS-審核4.3入坑(已出坑)
