androidkotlinandroid-jetpack-composeandroid-jetpackandroid-jetpack-compose-layout

Avoid side padding from particular child item of LazyColumn in jetpack compose


I want to removed side padding of particular child item in LazyColum. I solved this problem in xml with the help of this post. I have same scenario in the jetpack compose. I am using BOM versions of compose_bom = "2022.11.00" with Material 3.

    Card(shape = RoundedCornerShape(6.dp),) {
        Column(modifier.background(Color.White)) {
            LazyColumn(
                contentPadding = PaddingValues(all =16.dp),
                verticalArrangement = Arrangement.spacedBy(16.dp),
            ) {
                item {
                    Text(
                        text = "Device Header",
                        modifier = Modifier.padding(top = 10.dp),
                        style = headerTextStyle
                    )
                }

                item {
                    Divider() // remove padding from side in here
                }
            }
        }
    }

Actual Output

enter image description here

Expected Output

enter image description here


Solution

  • In Compose you can't use a negative padding in the children to reduce the padding applied by the parent container. You can use offset modifer with a negative value but it will shift the Divider on the left side.

    You can use a layout modifier to apply an horizontal offset increasing the width.

    Something like:

    LazyColumn(
        Modifier.background(Yellow),
        contentPadding = PaddingValues(all = 16.dp),
        verticalArrangement = Arrangement.spacedBy(16.dp),
    ) {
        //...
    
        item {
            val sidePadding = (-8).dp
    
     
            Divider(modifier = Modifier
                .layout { measurable, constraints ->
                    // Measure the composable adding the side padding*2 (left+right)
                    val placeable =
                        measurable.measure(constraints.offset(horizontal = -sidePadding.roundToPx() * 2))
    
                    //increase the width adding the side padding*2
                    layout(
                        placeable.width + sidePadding.roundToPx() * 2,
                        placeable.height
                    ) {
                        // Where the composable gets placed
                        placeable.place(+sidePadding.roundToPx(), 0)
                    }
    
                }
            )          
            
        }
    }
    

    Here you can find the output with a Divider() without modifier, and the Divider with the layout modifier.

    enter image description here