我是靠谱客的博主 冷静蜜蜂,最近开发中收集的这篇文章主要介绍一个简单的Android圆形ProgressBar使用kotlin实现一个简单的Android圆形ProgressBar,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

使用kotlin实现一个简单的Android圆形ProgressBar

本自定义View功能比较简单,就是一个包含百分比的圆形进度条,先上结果图(新手,大神勿喷)

进度条

代码如下所示,支持padding设置,背景线条颜色设置


<!--res/values/attrs.xml-->
<?xml version="1.0" encoding="utf-8"?>
<resources>
<declare-styleable name="CircleProgressBar">
<attr name="backgroundColor" format="color" />
<attr name="textColor" format="color" />
<attr name="arcWidth" format="integer" />
</declare-styleable>
</resources>
//CircleProgressBar.kt
package com.hefuwei.progressview
import android.content.Context
import android.graphics.Canvas
import android.graphics.Color
import android.graphics.Paint
import android.graphics.Rect
import android.os.Build
import android.support.annotation.RequiresApi
import android.util.AttributeSet
import android.view.View
/**
* Created by hefuwei on 2018/3/29.
*/
class CircleProgressBar(context:Context,set:AttributeSet?): View(context,set){
private val paint:Paint = Paint(Paint.ANTI_ALIAS_FLAG) //设置抗锯齿
private val smallestSize:Int = 150 //当设置为wrap_content时的最小尺寸
private var progress:Int = 0
private val arcWidth:Int //进度条外边缘线
private val boundRect = Rect()
init {
val typeArray = context.obtainStyledAttributes(set,R.styleable.CircleProgressBar)
setBackgroundColor(typeArray.getColor(R.styleable.CircleProgressBar_backgroundColor,Color.BLACK)) //获取xml定义的backgroundColor并设置
paint.color = typeArray.getColor(R.styleable.CircleProgressBar_textColor,Color.WHITE)
arcWidth = typeArray.getInt(R.styleable.CircleProgressBar_arcWidth,3)
paint.strokeWidth = arcWidth.toFloat()
typeArray.recycle() //回收typeArray 防止内存泄露
}
constructor(context: Context):this(context, null) //次构造器
@RequiresApi(Build.VERSION_CODES.LOLLIPOP) //偷个懒不用RectF
override fun onDraw(canvas: Canvas?) {
super.onDraw(canvas)
val width = measuredWidth - paddingLeft - paddingRight //获取实际可用于绘制的宽高
val height = measuredHeight - paddingBottom - paddingTop
if(canvas != null){
paint.style = Paint.Style.FILL //使用填充模式画文字
if(progress >= 10){
drawText("$progress%",canvas)
}else{
drawText("0$progress%",canvas)
}
paint.color = Color.RED
paint.style = Paint.Style.STROKE //使用画线模式画圆弧
if(height > width){ //计算圆弧位置 以最小边的一半为半径
canvas.drawArc(paddingLeft.toFloat()+arcWidth/2,
(height-width+arcWidth)/2.toFloat(),
measuredWidth.toFloat()-arcWidth/2-paddingRight,
(height+width+arcWidth)/2.toFloat(),
135f,2.7f*progress.toFloat(),false,paint)
} else {
canvas.drawArc((width-height)/2.toFloat(),
paddingTop.toFloat()+arcWidth/2,
(width+height)/2.toFloat(),
measuredHeight.toFloat()-arcWidth/2-paddingBottom,
135f,2.7f*progress.toFloat(),false,paint)
}
}
}
private fun drawText(str:String, canvas:Canvas){
paint.getTextBounds(str,0,str.length,boundRect) //注意drawText的起点是位于第一个字的左下
canvas.drawText(str,(measuredWidth-boundRect.right+boundRect.left+paddingLeft-paddingRight)/2.toFloat()
,(measuredHeight+boundRect.bottom-boundRect.top-paddingTop-paddingBottom)/2.toFloat(),paint)
}
override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec)
val widthSize = MeasureSpec.getSize(widthMeasureSpec)
val widthMode = MeasureSpec.getMode(widthMeasureSpec)
val heightSize = MeasureSpec.getSize(heightMeasureSpec)
val heightMode = MeasureSpec.getMode(heightMeasureSpec)
if(widthMode == MeasureSpec.AT_MOST && heightMode == MeasureSpec.AT_MOST){ //解决wrap_content与match_content效果一致的问题
setMeasuredDimension(smallestSize,smallestSize)
}else if(widthMode == MeasureSpec.AT_MOST){
setMeasuredDimension(smallestSize,heightSize)
}else if(heightMode == MeasureSpec.AT_MOST){
setMeasuredDimension(widthSize,smallestSize)
}
chooseRightTextSize() //选择合适的textSize避免text比外面的框大
}
private fun chooseRightTextSize(){
var lastSize = 1
for(i in 1..500){
paint.textSize = i.toFloat()
paint.getTextBounds("100%",0,"100%".length,boundRect)
if((boundRect.right - boundRect.left)*1.9 < measuredWidth-paddingLeft-paddingRight &&
(boundRect.bottom - boundRect.top)*4 < measuredHeight-paddingTop-paddingBottom){
lastSize = i
}else{
paint.textSize = lastSize.toFloat()
return
}
}
}
fun setProgress(progress:Int){
when {
progress < 0 -> this.progress = 0
progress > 100 -> this.progress = 100
else -> this.progress = progress
}
invalidate() //调用该方法后立即刷新视图
}
fun getProgress():Int = progress
}
//根据自己喜爱给progressBar设置背景,线条粗细
<!--res/layout/activity_main.xml-->
<?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="com.hefuwei.progressview.MainActivity">
<com.hefuwei.progressview.CircleProgressBar
android:id="@+id/cb"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_centerInParent="true"
app:arcWidth="40"
app:backgroundColor="#fff"
app:textColor="#000" />
</RelativeLayout>
  • 最后在MainActivity里面使用属性动画即可出现本文开头的动画
//MainActivity.kt
package com.hefuwei.progressview
import android.animation.ObjectAnimator
import android.support.v7.app.AppCompatActivity
import android.os.Bundle
import kotlinx.android.synthetic.main.activity_main.*
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val animator = ObjectAnimator.ofInt(cb,"progress",100)
animator.duration = 10000
animator.start()
}
}

最后附上github地址

最后

以上就是冷静蜜蜂为你收集整理的一个简单的Android圆形ProgressBar使用kotlin实现一个简单的Android圆形ProgressBar的全部内容,希望文章能够帮你解决一个简单的Android圆形ProgressBar使用kotlin实现一个简单的Android圆形ProgressBar所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(47)

评论列表共有 0 条评论

立即
投稿
返回
顶部