如何在 Jetpack Compose 中设置虚线边框?

Dav*_*him 7 android border android-jetpack-compose

我可以使用 轻松创建普通边框,Modifier.border()但如何创建虚线边框,如下图所示。

在此处输入图片说明

Gab*_*tti 62

没有参数可以Modifier.border()实现虚线路径。

但是,您可以使用 a来DrawScope绘制虚线。PathPathEffect.dashPathEffect

就像是:

val stroke = Stroke(width = 2f,
    pathEffect = PathEffect.dashPathEffect(floatArrayOf(10f, 10f), 0f)
)
Run Code Online (Sandbox Code Playgroud)

您可以使用修改器绘制它drawBehind

Box(
    Modifier
        .size(250.dp,60.dp)
        .drawBehind {
            drawRoundRect(color = Color.Red, style = stroke)
        },
    contentAlignment = Alignment.Center
) {
    Text(textAlign = TextAlign.Center,text = "Tap here to introduce yourseft")
}
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述

如果你想要圆角,只需使用方法cornerRadius中的属性drawRoundRect

drawRoundRect(color = Color.Red,style = stroke, cornerRadius = CornerRadius(8.dp.toPx()))
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述


如果您愿意,可以Modifier使用上面相同的代码构建您的自定义。就像是:

fun Modifier.dashedBorder(strokeWidth: Dp, color: Color, cornerRadiusDp: Dp) = composed(
    factory = {
        val density = LocalDensity.current
        val strokeWidthPx = density.run { strokeWidth.toPx() }
        val cornerRadiusPx = density.run { cornerRadiusDp.toPx() }

        this.then(
            Modifier.drawWithCache {
                onDrawBehind {
                    val stroke = Stroke(
                        width = strokeWidthPx,
                        pathEffect = PathEffect.dashPathEffect(floatArrayOf(10f, 10f), 0f)
                    )

                    drawRoundRect(
                        color = color,
                        style = stroke,
                        cornerRadius = CornerRadius(cornerRadiusPx)
                    )
                }
            }
        )
    }
)
Run Code Online (Sandbox Code Playgroud)

然后应用它:

Box(
    Modifier
        .size(250.dp,60.dp)
        .dashedBorder(1.dp, Red, 8.dp),
    contentAlignment = Alignment.Center
) {
    Text(
        text = "Tap here to introduce yourself",
        textAlign = TextAlign.Center,
    )
}
Run Code Online (Sandbox Code Playgroud)

  • @CôngHải 检查更新的答案。只需在drawRoundRect方法中使用cornerRadius属性即可。 (2认同)

Dav*_*him 16

在对正常边框修改器进行一番挖掘之后,我发现它使用Stroke对象,该对象可以采用可以使其成为虚线的参数PathEffect,这里是采用该参数的正常边框函数的修改版本。

https://gist.github.com/DavidIbrahim/236dadbccd99c4fd328e53587df35a21

  • 在上面的问题之后,我开始深入研究这个问题,并陷入了这个错误:“类型不匹配:推断的类型是 DashPathEffect,但 PathEffect 是预期的。” 这在 alpha-09 之前有效,但在 beta 上无效。在你的回答之后我就开始工作了。谢谢你! (2认同)

hos*_*ini 14

我为修改器编写了这个扩展,您可以简单地使用它或修改它。

fun Modifier.dashedBorder(width: Dp, radius: Dp, color: Color) = 
    drawBehind {
        drawIntoCanvas {
            val paint = Paint()
                .apply {
                    strokeWidth = width.toPx()
                    this.color = color
                    style = PaintingStyle.Stroke
                    pathEffect = PathEffect.dashPathEffect(floatArrayOf(10f, 10f), 0f)
        }
        it.drawRoundRect(
            width.toPx(),
            width.toPx(),
            size.width - width.toPx(),
            size.height - width.toPx(),
            radius.toPx(),
            radius.toPx(),
            paint
        )
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 按原样使用它,我的边框与视图的实际边缘有一点间隙。更新到此修复了 it.drawRoundRect( (width.toPx() / 2), (width.toPx() / 2), size.width - (width.toPx() / 2), size.height - (width. toPx() / 2), radius.toPx(), radius.toPx(), 绘制 ) (2认同)