You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何为环形滑动条(Circle SeekBar)填充当前值区域颜色?

环形滑动条(Circle SeekBar)当前值区域填充颜色实现方案

自定义View实现(推荐)

通过重写View的onDraw方法手动绘制背景环形和进度填充区域,同时支持触摸拖动调整进度,完全可控且无需依赖第三方库。

1. 定义自定义属性

在res/values/attrs.xml中添加配置属性,方便在布局中直接调整样式:

<declare-styleable name="CircleSeekBar">
    <attr name="progressColor" format="color" />
    <attr name="backgroundColor" format="color" />
    <attr name="maxProgress" format="integer" />
    <attr name="currentProgress" format="integer" />
    <attr name="circleWidth" format="dimension" />
</declare-styleable>

2. 编写自定义CircleSeekBar类

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

    private var progressColor: Int = Color.BLUE
    private var backgroundColor: Int = Color.GRAY
    private var maxProgress: Int = 100
    private var currentProgress: Int = 50
    private var circleWidth: Float = 20f
    private val paint = Paint(Paint.ANTI_ALIAS_FLAG)
    private val rectF = RectF()

    init {
        val typedArray = context.obtainStyledAttributes(attrs, R.styleable.CircleSeekBar)
        progressColor = typedArray.getColor(R.styleable.CircleSeekBar_progressColor, progressColor)
        backgroundColor = typedArray.getColor(R.styleable.CircleSeekBar_backgroundColor, backgroundColor)
        maxProgress = typedArray.getInt(R.styleable.CircleSeekBar_maxProgress, maxProgress)
        currentProgress = typedArray.getInt(R.styleable.CircleSeekBar_currentProgress, currentProgress)
        circleWidth = typedArray.getDimension(R.styleable.CircleSeekBar_circleWidth, circleWidth)
        typedArray.recycle()
    }

    override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
        val size = Math.min(MeasureSpec.getSize(widthMeasureSpec), MeasureSpec.getSize(heightMeasureSpec))
        setMeasuredDimension(size, size)
    }

    override fun onDraw(canvas: Canvas) {
        super.onDraw(canvas)
        val centerX = width / 2f
        val centerY = height / 2f
        val radius = Math.min(centerX, centerY) - circleWidth / 2

        // 绘制背景环形
        paint.color = backgroundColor
        paint.style = Paint.Style.STROKE
        paint.strokeWidth = circleWidth
        canvas.drawCircle(centerX, centerY, radius, paint)

        // 绘制进度填充环形
        paint.color = progressColor
        paint.style = Paint.Style.STROKE
        paint.strokeCap = Paint.Cap.ROUND // 可选:设置进度端点为圆角
        val sweepAngle = (currentProgress.toFloat() / maxProgress) * 360f
        rectF.set(centerX - radius, centerY - radius, centerX + radius, centerY + radius)
        canvas.drawArc(rectF, -90f, sweepAngle, false, paint)
    }

    // 对外暴露设置进度的方法
    fun setCurrentProgress(progress: Int) {
        currentProgress = progress.coerceIn(0, maxProgress)
        invalidate()
    }

    // 处理触摸拖动,实现交互式调整进度
    override fun onTouchEvent(event: MotionEvent): Boolean {
        when (event.action) {
            MotionEvent.ACTION_DOWN, MotionEvent.ACTION_MOVE -> {
                val centerX = width / 2f
                val centerY = height / 2f
                val dx = event.x - centerX
                val dy = event.y - centerY
                var angle = Math.toDegrees(Math.atan2(dy.toDouble(), dx.toDouble())).toFloat()
                if (angle < -90) angle += 360
                angle += 90 // 将起始角度调整为环形顶部
                val progress = ((angle / 360f) * maxProgress).toInt()
                setCurrentProgress(progress)
                return true
            }
        }
        return super.onTouchEvent(event)
    }
}

3. 在布局中使用

<com.yourpackage.CircleSeekBar
    android:layout_width="200dp"
    android:layout_height="200dp"
    app:progressColor="@color/blue"
    app:backgroundColor="@color/light_gray"
    app:maxProgress="100"
    app:currentProgress="50"
    app:circleWidth="20dp" />

核心逻辑说明

  • 通过canvas.drawArc绘制对应进度的弧形区域,sweepAngle由当前进度与最大进度的比例计算得出,精准匹配当前值区域。
  • 触摸事件中通过计算触摸点与中心的夹角,转换为对应的进度值,实现拖动交互。

内容的提问来源于stack exchange,提问作者JAEYUN

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.20 16:00:20