androidandroid-jetpackandroid-jetpack-compose

how to add border on bottom only in jetpack compose


I want to add border on bottom of the layout. I know i can use Divider composable but i just want to learn how to draw a border.

Currently, I can add border for all sides which is not what I want.

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

Solution

  • You can use the drawBehind modifier to draw a line.
    Something like:

    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
                )
            }){
        //....
    }
    

    enter image description here

    If you prefer you can build your custom Modifier with the same code above

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

    and then just apply it:

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