经验首页 前端设计 程序设计 Java相关 移动开发 数据库/运维 软件/图像 大数据/云计算 其他经验
当前位置:技术经验 » 移动开发 » Android » 查看文章
kotlin 圆形进度条
来源:cnblogs  作者:翻滚的咸鱼  时间:2021/3/1 8:41:59  对本文有异议

kotlin版的自定义圆形进度条

大多数启动页都会带个进度条加载样式,所以就自己用kotlin重新写了一个,如果真的要很炫酷还是有很多东西可以附加的

一个简单的进度条基本组成就是一个背景环,一个进度环,需要注意的就是绘制的方式了

因为圆形进度条是宽高对等的,我们定义view宽高可能不是对等的,所以绘制的时候需要计算中间绘制,不然绘制的结果可能不是你理想的,比如下面右上角

 

 

 

当然,如果只是两个环,感觉有点丑,不是很美观,可以添加一点元素让它稍微的美观一点,比如绘制一个进度百分比提示文字,圆环自定义颜色,中心在绘制一个中心圆,这样通过配置颜色要比两个单调的圆环美观许多

然后还可以加入一点初始化或者结束的view动画,这边我加了一个进入缩放动画,开始拿起键盘一把梭

1.初始化

画笔,配置颜色背景,字体,进度等都需要用到自定义属性,所以初始化的时候需要把这些参数都实例化,然后刚才加入的缩放动画也是在初始化里

在xml里定义好style

  1. <?xml version="1.0" encoding="utf-8"?>
  2. <resources>
  3. <declare-styleable name="circleProgress">
  4. <attr name="circle_max" format="float" />
  5. <attr name="circle_progress" format="float" />
  6. <attr name="circle_width" format="dimension" />
  7. <attr name="circle_progress_color" format="color" />
  8. <attr name="circle_color" format="color" />
  9. <attr name="circle_text_color" format="color" />
  10. <attr name="circle_text_size" format="dimension" />
  11. <attr name="circle_text_isBold" format="boolean" />
  12. <attr name="circle_center_color" format="color" />
  13. </declare-styleable>
  14. </resources>

然后编写init方法

  1. private fun init() {
  2. //自定义属性
  3. val attributes: TypedArray = context.obtainStyledAttributes(
  4. attrs,
  5. R.styleable.circleProgress
  6. )
  7. mStrokeWidth = attributes.getDimension(R.styleable.circleProgress_circle_width, 1f)
  8. max = attributes.getFloat(R.styleable.circleProgress_circle_max, 100f)
  9. mProgress = attributes.getFloat(R.styleable.circleProgress_circle_progress, 0f)
  10. val bgColor = attributes.getColor(R.styleable.circleProgress_circle_color,Color.GRAY)
  11. val progressColor = attributes.getColor(R.styleable.circleProgress_circle_progress_color,Color.BLUE)
  12. val textColor = attributes.getColor(R.styleable.circleProgress_circle_text_color,Color.BLACK)
  13. val textSize = attributes.getDimension(R.styleable.circleProgress_circle_text_size,SizeUtils.dp2px(10f).toFloat())
  14. val isBold = attributes.getBoolean(R.styleable.circleProgress_circle_text_isBold,false)
  15. val centerColor = attributes.getColor(R.styleable.circleProgress_circle_center_color,Color.TRANSPARENT)
  16. attributes.recycle()
  17. //圆环画笔
  18. bgPaint = Paint()
  19. bgPaint.style = Paint.Style.STROKE
  20. bgPaint.strokeWidth = mStrokeWidth
  21. bgPaint.color = bgColor
  22. bgPaint.isAntiAlias = true
  23. //中心圆画笔
  24. centerPaint = Paint()
  25. centerPaint.style = Paint.Style.FILL
  26. centerPaint.color = centerColor
  27. centerPaint.isAntiAlias = true
  28. //进度条画笔
  29. tintPaint = Paint()
  30. tintPaint.style = Paint.Style.STROKE
  31. tintPaint.strokeWidth = mStrokeWidth
  32. tintPaint.strokeCap = Paint.Cap.ROUND
  33. tintPaint.color = progressColor
  34. tintPaint.isAntiAlias = true
  35. //文字画笔
  36. textPaint = Paint()
  37. textPaint.style = Paint.Style.FILL
  38. textPaint.textSize = textSize
  39. textPaint.textAlign = Paint.Align.CENTER
  40. textPaint.isFakeBoldText = isBold
  41. textPaint.color = textColor
  42. textPaint.isAntiAlias = true
  43. initAnimation()
  44. }
View Code

2.测量

因为宽高是不可控的,你不知道具体设置成什么样子,有的是宽高尺寸一样,有的是宽大于高等,所以圆形直径需要取最小值,这样才能绘制成一个完整的圆形

  1. override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
  2. super.onMeasure(widthMeasureSpec, heightMeasureSpec)
  3. mWidth = getRealSize(widthMeasureSpec)
  4. mHeight = getRealSize(heightMeasureSpec)
  5. /** 直径 - 等宽高充满 | 当宽高不一致时,取最小的画圆 */
  6. val diameter = min(mWidth,mHeight)
  7. //半径
  8. mRadius = diameter / 2f - mStrokeWidth
  9. /** 进度条绘制区域 */
  10. val mX = mWidth/2f-diameter/2
  11. val mY = mHeight/2f-diameter/2
  12. mRect = RectF(mX + mStrokeWidth, mY + mStrokeWidth, mX + diameter - mStrokeWidth, mY + diameter - mStrokeWidth)
  13. setMeasuredDimension(mWidth,mHeight)
  14. }

3.draw

圆形直接drawCircle绘制,进度条就需要绘制扇形了,然后通过传过来的进度条,计算扇形的角度,百分比文字就是在圆形中心点绘制

  1. override fun onDraw(canvas: Canvas?) {
  2. super.onDraw(canvas)
  3. val progress = mProgress / max * 360
  4. //绘制圆形
  5. canvas!!.drawCircle(mWidth / 2f, mHeight / 2f, mRadius, bgPaint)
  6. //绘制中心圆
  7. canvas.drawCircle(mWidth / 2f, mHeight / 2f, mRadius, centerPaint)
  8. //绘制进度
  9. canvas.drawArc(mRect, -90f, progress, false, tintPaint)
  10. //绘制文字(百分比)
  11. val percentage: Int = (mProgress / max * 100).toInt()
  12. val centerY = mHeight / 2 + mStrokeWidth / 2
  13. canvas.drawText("${percentage}%", mWidth / 2f, centerY, textPaint)
  14. }

就是这么简单,主要逻辑其实就在测量跟绘制

然后对外扩展设置进度,刷新视图

 

使用:

binding.pbTime.setProgress(count)

这里模拟一下加载进度,效果图见最上方

 

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

原文链接:http://www.cnblogs.com/LiuZhen/p/14446023.html

 友情链接:直通硅谷  点职佳  北美留学生论坛

本站QQ群:前端 618073944 | Java 606181507 | Python 626812652 | C/C++ 612253063 | 微信 634508462 | 苹果 692586424 | C#/.net 182808419 | PHP 305140648 | 运维 608723728

W3xue 的所有内容仅供测试,对任何法律问题及风险不承担任何责任。通过使用本站内容随之而来的风险与本站无关。
关于我们  |  意见建议  |  捐助我们  |  报错有奖  |  广告合作、友情链接(目前9元/月)请联系QQ:27243702 沸活量
皖ICP备17017327号-2 皖公网安备34020702000426号