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

Android Drawable中如何为虚线圆形描边设置渐变色

渐变虚线圆形描边实现方案

原生XML Shape方案无法实现该效果:<shape>标签下的<stroke>节点仅支持纯色配置,内置的<gradient>节点仅对图形填充区域生效,无法作用于描边,更无法适配虚线描边的渐变需求。

最稳定的实现方案是自定义Drawable,通过DashPathEffect实现虚线效果,SweepGradient实现环形渐变描边,代码如下:

class GradientDashCircleDrawable(
    private val strokeWidthPx: Float,
    private val dashWidthPx: Float,
    private val dashGapPx: Float,
    private val gradientColors: IntArray
) : Drawable() {

    private val paint = Paint(Paint.ANTI_ALIAS_FLAG).apply {
        style = Paint.Style.STROKE
        strokeWidth = strokeWidthPx
        // 配置虚线规则
        pathEffect = DashPathEffect(floatArrayOf(dashWidthPx, dashGapPx), 0f)
    }
    private val drawRect = RectF()

    override fun onBoundsChange(bounds: Rect) {
        super.onBoundsChange(bounds)
        // 预留描边宽度,避免边缘被裁切
        val inset = strokeWidthPx / 2f
        drawRect.set(
            bounds.left + inset,
            bounds.top + inset,
            bounds.right - inset,
            bounds.bottom - inset
        )
        // 配置环形扫描渐变,适配圆形描边
        paint.shader = SweepGradient(
            drawRect.centerX(),
            drawRect.centerY(),
            gradientColors,
            null
        )
    }

    override fun draw(canvas: Canvas) {
        canvas.drawOval(drawRect, paint)
    }

    override fun setAlpha(alpha: Int) {
        paint.alpha = alpha
    }

    override fun setColorFilter(colorFilter: ColorFilter?) {
        paint.colorFilter = colorFilter
    }

    @Deprecated("Deprecated in Java", ReplaceWith("PixelFormat.TRANSLUCENT"))
    override fun getOpacity(): Int = PixelFormat.TRANSLUCENT

    // 配置默认尺寸,对应原XML里的60dp大小,适配wrap_content场景
    override fun getIntrinsicWidth(): Int = (60 * Resources.getSystem().displayMetrics.density).toInt()
    override fun getIntrinsicHeight(): Int = (60 * Resources.getSystem().displayMetrics.density).toInt()
}

使用方式

直接在代码中初始化Drawable并设置给View即可,注意所有尺寸参数需要提前转换为px单位:

val gradientDashDrawable = GradientDashCircleDrawable(
    strokeWidthPx = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 1f, resources.displayMetrics),
    dashWidthPx = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 3f, resources.displayMetrics),
    dashGapPx = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 1f, resources.displayMetrics),
    gradientColors = intArrayOf(
        Color.parseColor("#FF3DA9FC"),
        Color.parseColor("#FF9B51E0"),
        Color.parseColor("#FFFF7A59"),
        Color.parseColor("#FF3DA9FC") // 首尾颜色保持一致,避免环形渐变出现断层
    )
)
findViewById<View>(R.id.circle_view).background = gradientDashDrawable

效果参考

  • 当前已实现的纯色虚线圆形效果:
    已实现的纯色虚线效果
  • 目标渐变虚线圆形效果:
    目标渐变虚线效果

补充说明

  • 该方案兼容API 21及以上版本,无兼容问题
  • 如果需要调整渐变效果,可以替换SweepGradient为LinearGradient(线性渐变)、RadialGradient(径向渐变),也可以传入颜色位置参数自定义渐变分布
  • 如果需要静态使用,也可以基于该逻辑自定义View,在onDraw方法中完成绘制即可

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.01 13:15:40