I didn't find any way to have a stickyHeader on the same line as an item in a LazyColumn:
So I used a Box to put the letter with its background on top of the LazyColumn and used the LazyListState to put it in the right position :
@Preview
@Composable
fun InlineStickyList() {
val unsorted = listOf(...) // Pair("FirstName","LastName")
val data = unsorted.sortedBy { it.second[0] }
val groups = data.groupBy { it.second[0] }
@Composable
fun Person(pair: Pair<String, String>, showLetter: Boolean) {
Row(
modifier = Modifier
.fillMaxWidth()
.background(Color.White),
verticalAlignment = Alignment.CenterVertically
) {
Text(
"${pair.second[0]}",
modifier = Modifier
.padding(10.dp)
.alpha(if (showLetter) 1f else 0f),
fontSize = 20.sp
)
Text("${pair.first} ${pair.second}")
}
}
val state = rememberLazyListState()
Box(modifier = Modifier.fillMaxSize()) {
LazyColumn(modifier = Modifier.fillMaxSize(), state = state) {
groups.forEach { (_, group) ->
item {
Person(group[0], true)
}
items(group.subList(1, group.size)) {
Person(it, false)
}
}
}
}
val letter =
data[state.firstVisibleItemIndex].second[0]
val next =
data[state.firstVisibleItemIndex + 1].second[0]
Text(
"$letter",
fontSize = 20.sp,
modifier = Modifier
.clipToBounds()
.offset(y = if (letter != next) -with(LocalDensity.current) {
state.firstVisibleItemScrollOffset.toDp()
} else 0.dp)
.background(Color.White)
.padding(start = 10.dp, top = 10.dp, bottom = 10.dp),
)
}
Is there another way to achieve that ? (cleaner/better)