美文网首页
自定义圆弧进度条(Kotlin&Compose)

自定义圆弧进度条(Kotlin&Compose)

作者: 愿天深海 | 来源:发表于2023-07-06 19:29 被阅读0次

开始使用compose了之后才发现一些以前需要自定义的view,洋洋洒洒几十上百行的代码,需要自定义布局属性,需要继承View,需要使用Paint,如果使用Compose,直接一个方法二十行即可解决。

来实现下图所示一个自定义圆弧进度条:


圆弧进度条

使用Kotlin实现

早期有写过这么一个小demo
完整代码见:https://github.com/yaoxiawen/CircleProgressBar

自定义布局属性

在attrs.xml(如没有则创建)中定义需要的属性

    <!--圆环形进度条-->
    <declare-styleable name="CircleProgressBar">
        <attr name="ringMax" format="integer" />
        <attr name="progress" format="integer" />
        <attr name="startAngle" format="float" />
        <attr name="endAngle" format="float" />
        <attr name="reverse" format="boolean" />
        <attr name="roundCap" format="boolean" />
        <attr name="ringWidth" format="dimension" />
        <attr name="ringColor" format="color" />
        <attr name="ringBackgroundColor" format="color" />
    </declare-styleable>

自定义View

创建CircleProgressBar继承View

class CircleProgressBar @JvmOverloads constructor(
    context: Context, attrs: AttributeSet? = null, @AttrRes defStyleAttr: Int = 0
) : View(context, attrs, defStyleAttr) 

通过AttributeSet解析属性

通过构造函数中AttributeSet参数解析布局中传入的属性值,所有属性都需要有默认值

        val ta = context.obtainStyledAttributes(attrs, R.styleable.CircleProgressBar)
        max = ta.getInt(R.styleable.CircleProgressBar_ringMax, DEFAULT_MAX)
        if (max <= 0) {
            max = DEFAULT_MAX
        }
        startAngle = ta.getFloat(R.styleable.CircleProgressBar_startAngle, DEFAULT_START_ANGLE)
        endAngle = ta.getFloat(R.styleable.CircleProgressBar_endAngle, DEFAULT_END_ANGLE)
        reverse = ta.getBoolean(R.styleable.CircleProgressBar_reverse, DEFAULT_REVERSE)
        roundCap = ta.getBoolean(R.styleable.CircleProgressBar_roundCap, DEFAULT_ROUND_CAP)
        progress = ta.getInt(R.styleable.CircleProgressBar_progress, DEFAULT_PROGRESS)
        ringWidth =
            ta.getDimension(R.styleable.CircleProgressBar_ringWidth, DEFAULT_RING_WIDTH)
        ringColor = ta.getColor(R.styleable.CircleProgressBar_ringColor, DEFAULT_RING_COLOR)
        ringBackgroungColor = ta.getColor(
            R.styleable.CircleProgressBar_ringBackgroundColor,
            DEFAULT_RING_BACKGROUND_COLOR
        )
        ta.recycle()

初始化Paint

自定义view使用canvas进行绘制,自然是需要有Paint

        mArcPaint = Paint()
        mArcPaint.isAntiAlias = true

onDraw中绘制圆弧

使用canvas的drawArc绘制圆弧,Paint设置strokeCap为Paint.Cap.ROUND可画出圆帽的效果。

        with(mArcPaint) {
            color = ringBackgroungColor
            style = Paint.Style.STROKE
            strokeWidth = ringWidth
            if (roundCap) {
                strokeCap = Paint.Cap.ROUND
            }
        }
        //绘制圆环背景
        canvas.drawArc(mRectF, startAngle, endAngle - startAngle, false, mArcPaint)
        with(mArcPaint) {
            color = ringColor
            if (roundCap) {
                strokeCap = Paint.Cap.ROUND
            }
        }
        var sweepAngle = progress.toFloat() / max * (endAngle - startAngle)
        if (reverse) {
            sweepAngle = -sweepAngle  //逆时针滚动
        }
        canvas.drawArc(mRectF, startAngle, sweepAngle, false, mArcPaint)

xml布局中使用

    <com.example.circleprogressbar.CircleProgressBar
        android:layout_width="200dp"
        android:layout_height="200dp"
        app:progress="30"
        app:startAngle="-225"
        app:endAngle="45"
        app:ringWidth="10dp" />

使用Compose实现

类似的一些API,使用Canvas的drawArc绘制圆弧,设置cap = StrokeCap.Round可以达到圆帽的效果。

@Composable
fun CircleProgress(
    modifier: Modifier = Modifier,
    progress: Int,
    startAngle: Float,
    endAngle: Float,
    progressBgColor: Color,
    progressColor: Color,
) {
    Canvas(
        modifier = modifier,
        onDraw = {
            drawArc(
                color = progressBgColor,
                startAngle = startAngle,
                sweepAngle = endAngle - startAngle,
                useCenter = false,
                style = Stroke(size.width / 11, cap = StrokeCap.Round)
            )
            drawArc(
                color = progressColor,
                startAngle = startAngle,
                sweepAngle = (endAngle - startAngle) * progress / 100,
                useCenter = false,
                style = Stroke(size.width / 11, cap = StrokeCap.Round)
            )
        }
    )
}

调用方法传入相应的一些参数,参数也可直接设置有默认值。

        CircleProgress(
            modifier = Modifier.padding(5.dp).size(66.dp),
            startAngle = -225f,
            endAngle = 45f,
            progress = 30,
            progressBgColor = Color.LightGray,
            progressColor = Color.Blue
        )

相关文章

  • Android 圆形进度条

    可设置 线性渐变-背景色-进度条颜色-圆弧宽度效果图 步骤一:新建自定义控件CirclePercentView继承...

  • 自定义 View 实战 04 - 圆形进度条

    圆形进度条分析: 圆 圆弧 进度值 所以这里我们先用 drawCircle画出圆,再使用drawArc画出圆弧(这...

  • Android自定义圆弧进度条

    挺久没写文章了,近段时间被拉过去写JS项目了,在做一个项目的时候,遇到一个新的需求就是空气质量,实现空气污染指数的...

  • 自定义 View 实战 02 - 圆弧形进度条

    内圆弧 外圆弧 中间文字 实现过程及注释 自定义属性 具体实现 调用 自定义圆弧就这样实现出来了,从 0 到 1 ...

  • 圆弧进度条

    已经很久没有写文章了,这次来说说环形进度条吧。 如上图所示,与设计稿还原度99%,本来想忽悠设计师用echars的...

  • iOS 的颜色渐变圆弧

    iOS 的颜色渐变 实现一个圆弧进度条主要分为三步 一、画圆弧这里用的贝赛尔曲线,就是这个东西:UIBezierP...

  • 自定义圆形进度条

    原理就是画一个圆弧,然后用内圆去覆盖圆弧实心的地方,然后写一个监听去时时更新进度条的进度.分为外圆,内圆,文字进度...

  • IDEA 插件开发-下载原生进度条

    分享几种IDEA 插件开发时原生下载方式和进度条自定义方法。 下载文件到本地 进度条自定义

  • Android-自定义ProgressBar实现圆弧进度条

    继承于ProgressBar实现,保留了Progressbar的特性,源码在文尾。。 参数 interface 提...

  • 2019-05-09

    圆形进度条,网上代码一大片,就不多说了 现在要实现的是进度圆弧,设置圆弧的起始点颜色和终点颜色 而不是设置半圆的起...

网友评论

      本文标题:自定义圆弧进度条(Kotlin&Compose)

      本文链接:https://www.haomeiwen.com/subject/foaludtx.html