What is the ItemDecoration for Jetpack Compose LazyColumn?

27.1k views Asked by At

In JetpackCompose, we can use LazyColumnFor as RecyclerView.

In RecyclerView, to have a proper margin/padding between items, we need to use ItemDecoration, as per this article

Like below

class MarginItemDecoration(private val spaceHeight: Int) : RecyclerView.ItemDecoration() {
    override fun getItemOffsets(outRect: Rect, view: View,
                                parent: RecyclerView, state: RecyclerView.State) {
        with(outRect) {
            if (parent.getChildAdapterPosition(view) == 0) {
                top = spaceHeight
            }
            left =  spaceHeight
            right = spaceHeight
            bottom = spaceHeight
        }
    }
}

For JetpackCompose LazyColumnFor, what's the equivalent of ItemDecoration?

4

There are 4 answers

0
Elye On

I kind of workaround using contentPadding of LazyColumnFor for top, start and end padding, and Spacer as the bottom padding for all items.

@Composable
fun MyComposeList(
    modifier: Modifier = Modifier,
    listItems: List<String>,
) {
    LazyColumnFor(
        modifier = modifier, items = listItems,
        contentPadding = PaddingValues(16.dp, 16.dp, 16.dp)
    ) { itemText ->
        ViewItem(
            itemText = itemText
        )
        Spacer(modifier = Modifier.fillMaxWidth().height(16.dp))
    }
}

This seems to get the result I needed, as the contentPadding can be scrolled together within the LazyColumnFor

3
Gabriele Mariotti On

You can use the verticalArrangement parameter to add a spacing between each item using Arrangement.spacedBy().

Something like:

LazyColumn(
    verticalArrangement = Arrangement.spacedBy(8.dp),
) {
    // ...
}

The example below adds 8.dp of space in-between each item

Before and after:
enter image description here enter image description here

If you want to add padding around the edges of the content you can use the contentPadding parameter.

  LazyColumn(
        verticalArrangement = Arrangement.spacedBy(8.dp),
        contentPadding = PaddingValues(horizontal = 24.dp, vertical = 8.dp)
  ){ ...  }

In the example above, the first item will add 8.dp padding to it’s top, the last item will add 8.dp to its bottom, and all items will have 24.dp padding on the left and the right.

enter image description here

0
Noah On

You can use LazyColumn with itemsIndexed (formerly LazyColumnForIndexed, deprecated) and apply the padding depending on the index.

LazyColumn {
  itemsIndexed(items = ...) { index, item ->
    Box(Modifier.padding(
      start = 16.dp, end = 16.dp, bottom = 16.dp, top = if (index == 0) 16.dp else 0.dp
    ))
  }
}
0
Đốc.tc On

The tutorial comes from the code lab you should refer to for a good plan https://developer.android.com/codelabs/jetpack-compose-layouts?continue=https%3A%2F%2Fdeveloper.android.com%2Fcourses%2Fpathways%2Fjetpack-compose-for-android-developers-1%23codelab-https%3A%2F%2Fdeveloper.android.com%2Fcodelabs%2Fjetpack-compose-layouts#6

LazyRow(
    modifier = modifier.padding(top = 16.dp, bottom = 16.dp),
    horizontalArrangement = Arrangement.spacedBy(8.dp),
    contentPadding = PaddingValues(horizontal = 8.dp)
) {
    items(alignYourBodyData) { item ->
        AlignYourBodyElement(
            drawable = item.drawable,
            text = item.text
        )
    }
}