как добавить границу внизу только в jetpack compose

#android #android-jetpack #android-jetpack-compose

Вопрос:

Я хочу добавить границу в нижней части макета. Я знаю, что могу использовать Divider composable, но я просто хочу научиться рисовать границу.

В настоящее время я могу добавить границу для всех сторон, чего я не хочу

 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)
            }
 

Комментарии:

1. AFAIK для этого нет функциональности. Рассматривали ли вы возможность добавления еще одного дочернего элемента для области строки, который действует как граница?

2. Удивительно, что для этого нет простого решения! Использование разделителя кажется мне лучшим решением!

Ответ №1:

Вы можете использовать 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
            )
        }){
    //....
}
 

введите описание изображения здесь

Комментарии:

1. Мне не нравится это решение, но оно довольно простое и работает. 😉

Ответ №2:

Вы можете нарисовать линию в области рисования. На мой взгляд, разделитель в коде выглядит чище.

 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
    }
)

 

Комментарии:

1. Именно так реализован исходный модификатор границы.