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
相关产品推荐
相关产品推荐

