Returns the TransformingLazyColumnFirstLayoutItemProvider.ItemInfo for the first visible item aligned to its TransformingLazyColumnFirstLayoutItemProvider.ItemEdge.Start edge, or null if there are no visible items.
@Preview
@Composable
fun TransformingLazyColumnFirstVisibleItemLayoutItemProviderSample() {
val transformationSpec = rememberTransformationSpec()
val state = rememberTransformingLazyColumnState()
var elements by remember { mutableStateOf(listOf(0, 1, 2, 3, 4, 5, 6, 7, 8, 9)) }
var nextElement by remember { mutableIntStateOf(10) }
fun addCardAfter(index: Int) {
elements =
elements.subList(0, index + 1) +
listOf(nextElement++) +
elements.subList(index + 1, elements.count())
}
fun removeCardAt(index: Int) {
elements = elements.subList(0, index) + elements.subList(index + 1, elements.count())
}
// This sample demonstrates how to use rememberTransformingLazyColumnFirstVisibleItemProvider
// to maintain a stable viewport top when items are added or removed dynamically.
// It achieves this by using the first visible item as the layout reference.
AppScaffold {
ScreenScaffold(state) { contentPadding ->
TransformingLazyColumn(
state = state,
contentPadding = contentPadding,
firstLayoutItemProvider =
rememberTransformingLazyColumnFirstLayoutItemProvider {
if (state.isScrollInProgress) null else state.firstVisibleItemLayoutItemInfo
},
) {
itemsIndexed(elements, key = { _, key -> key }) { index, cardKey ->
Card(
onClick = {},
modifier =
Modifier.minimumVerticalContentPadding(
CardDefaults.minimumVerticalListContentPadding
)
.transformedHeight(this, transformationSpec)
.animateItem(),
transformation = SurfaceTransformation(transformationSpec),
) {
Text("Card $cardKey")
Row {
Spacer(modifier = Modifier.weight(1f))
CompactButton(
onClick = { removeCardAt(index) },
enabled = elements.count() > 1,
) {
Text("-")
}
CompactButton(onClick = { addCardAfter(index) }) { Text("+") }
}
}
}
}
}
}
}