zoukankan      html  css  js  c++  java
  • kotlin 圆形进度条

    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

  • 相关阅读:
    安装redis报错 you need tcl 8.5 or newer in order to run redis test
    wm_concat函数oracle 11g返回clob
    ArrayList去重
    虚拟机linux下安装tomcat外部可访问
    虚拟机下Linux安装jdk
    本地硬盘和虚拟机之间复制文件
    VMware中为Linux安装vm-tools
    windows操作系统下载tomcat,并与eclipse进行整合
    Windows配置java运行环境的步骤
    Mac配置java运行环境的步骤
  • 原文地址:https://www.cnblogs.com/LiuZhen/p/14446023.html
Copyright © 2011-2022 走看看