Composables UI is out: our new component library for Compose Multiplatform ->
Property

firstVisibleItemLayoutItemInfo

Returns the TransformingLazyColumnFirstLayoutItemProvider.ItemInfo for the first visible item aligned to its TransformingLazyColumnFirstLayoutItemProvider.ItemEdge.Start edge, or null if there are no visible items.

TransformingLazyColumnFirstVisibleItemLayoutItemProviderSample

@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("+") }
                        }
                    }
                }
            }
        }
    }
}

Last updated: