如何在 Jetpack Compose 中仅在底部添加边框

问题描述 投票:0回答:6

我想在布局的bottom 上添加边框。我知道我可以使用

Divider
可组合但我只想学习如何绘制边框.

目前,我可以为所有边添加边框,这不是我想要的。

Row(
    modifier = Modifier
        .border(border = BorderStroke(width = 1.dp, Color.LightGray))
) {
    TextField(value = "", onValueChange = {}, modifier = Modifier.weight(1f))
    Switch(checked = true, onCheckedChange = {})
    Icon(Icons.Filled.Close, "Remove", tint = Color.Gray)
}
android android-jetpack android-jetpack-compose
6个回答
20
投票

您可以使用

drawBehind
修饰符画一条线。
像这样的东西:

Row(
    modifier = Modifier
        .drawBehind {

            val strokeWidth = indicatorWidth.value * density
            val y = size.height - strokeWidth / 2

            drawLine(
                Color.LightGray,
                Offset(0f, y),
                Offset(size.width, y),
                strokeWidth
            )
        }){
    //....
}

如果您愿意,可以使用上面相同的代码构建自定义修改器

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

        Modifier.drawBehind {
            val width = size.width
            val height = size.height - strokeWidthPx/2

            drawLine(
                color = color,
                start = Offset(x = 0f, y = height),
                end = Offset(x = width , y = height),
                strokeWidth = strokeWidthPx
            )
        }
    }
)

然后应用它:

Row(
    modifier = Modifier
        .padding(horizontal = 8.dp)
        .fillMaxWidth()
        .bottomBorder(1.dp, DarkGray)
){
    //Row content
}

3
投票

您可以在绘制范围内绘制一条线。在我看来,分隔线在代码中看起来更干净。

Row(modifier = Modifier
  .drawWithContent {
    drawContent()
    clipRect { // Not needed if you do not care about painting half stroke outside
      val strokeWidth = Stroke.DefaultMiter
      val y = size.height // - strokeWidth 
          // if the whole line should be inside component
      drawLine(
        brush = SolidColor(Color.Red),
        strokeWidth = strokeWidth,
        cap = StrokeCap.Square,
        start = Offset.Zero.copy(y = y),
        end = Offset(x = size.width, y = y)
      )
    }
  }
) {
  Text("test")
}

3
投票

是的,应该这样做:-

@Suppress("UnnecessaryComposedModifier")
fun Modifier.topRectBorder(width: Dp = Dp.Hairline, brush: Brush = SolidColor(Color.Black)): Modifier = composed(
    factory = {
        this.then(
            Modifier.drawWithCache {
                onDrawWithContent {
                    drawContent()
                    drawLine(brush, Offset(width.value, 0f), Offset(size.width - width.value, 0f))
                }
            }
        )
    },
    inspectorInfo = debugInspectorInfo {
        name = "border"
        properties["width"] = width
        if (brush is SolidColor) {
            properties["color"] = brush.value
            value = brush.value
        } else {
            properties["brush"] = brush
        }
        properties["shape"] = RectangleShape
    }
)


3
投票

您可以在元素的底部定义一个矩形形状,使用底线粗细作为参数:

private fun getBottomLineShape(bottomLineThickness: Float) : Shape {
    return GenericShape { size, _ ->
        // 1) Bottom-left corner
        moveTo(0f, size.height)
        // 2) Bottom-right corner
        lineTo(size.width, size.height)
        // 3) Top-right corner
        lineTo(size.width, size.height - bottomLineThickness)
        // 4) Top-left corner
        lineTo(0f, size.height - bottomLineThickness)
    }
}

然后像这样在边框修饰符中使用它:

val lineThickness = with(LocalDensity.current) {[desired_thickness_in_dp].toPx()}
Row(
    modifier = Modifier
       .height(rowHeight)
       .border(width = lineThickness,
               color = Color.Black,
               shape = getBottomLineShape(lineThickness))
) {
  // Stuff in the row
}

0
投票

使用“分隔线”对我有用,

Column {
        Divider (
            color = Color.White,
            modifier = Modifier
                .height(1.dp)
                .fillMaxHeight()
                .fillMaxWidth()
        )
        Row(
            verticalAlignment = Alignment.CenterVertically,
            modifier = Modifier
                .fillMaxWidth()
        ) {
// Something else
        }
    }


0
投票

可以用

drawBehind
修饰符画底线

这里有一个简单的例子,你可以怎么做

Column(modifier = Modifier.drawBehind {
                val borderSize = 3.dp.toPx()
                drawLine(
                    color = Color.White,
                    start = Offset(0f, size.height),
                    end = Offset(size.width, size.height),
                    strokeWidth = borderSize
                )
            },
        ) {
         ...
        }

这就是你如何使用它,但如果你想在多个地方使用它,那么简单的使用功能而不是应用手动边框

让我在这里提供任何人都可以使用的简单功能。

fun Modifier.drawBottomLine(lineSize: Int) = run {
    drawBehind {
    val borderSize = lineSize.dp.toPx()
    drawLine(
        color = Color.White,
        start = Offset(0f, size.height),
        end = Offset(size.width, size.height),
        strokeWidth = borderSize
    )
}}

然后像这样使用它:

Column(modifier = Modifier.drawBottomLine(3)) {
     ...
    }

这是输出

© www.soinside.com 2019 - 2024. All rights reserved.