Start native apps faster with the Composables CLI ->
Composable Function

TransformingLazyColumn

The vertically scrolling list that only composes and lays out the currently visible items.

SimpleTransformingLazyColumnSample

@Preview
@Composable
fun SimpleTransformingLazyColumnSample() {
    val transformationSpec = rememberTransformationSpec()
    TransformingLazyColumn(contentPadding = PaddingValues(20.dp)) {
        items(count = 10) { index ->
            Button(
                modifier = Modifier.fillMaxWidth().transformedHeight(this, transformationSpec),
                transformation = SurfaceTransformation(transformationSpec),
                onClick = {},
            ) {
                Text(text = "Item $index")
            }
        }
    }
}

TransformingLazyColumnPinnableContainerSample

@Preview
@Composable
fun TransformingLazyColumnPinnableContainerSample() {
    val state = rememberTransformingLazyColumnState()
    val transformationSpec = rememberTransformationSpec()
    TransformingLazyColumn(state = state, contentPadding = PaddingValues(horizontal = 20.dp)) {
        items(count = 20) { index ->
            var isPinned by remember { mutableStateOf(false) }
            var pinHandle by remember { mutableStateOf<PinnableContainer.PinnedHandle?>(null) }
            val pinnableContainer = LocalPinnableContainer.current
            // This state will be reset if the item is scrolled out and not pinned
            var counter by remember { mutableIntStateOf(0) }
            TitleCard(
                onClick = { counter++ },
                modifier = Modifier.fillMaxWidth().transformedHeight(this, transformationSpec),
                transformation = SurfaceTransformation(transformationSpec),
                title = { Text("Item $index") },
                subtitle = { Text("Count: $counter (Tap card to +)") },
                content = {
                    // This button toggles the pin state
                    Button(
                        onClick = {
                            if (isPinned) {
                                pinHandle?.release().also { pinHandle = null }
                                isPinned = false
                            } else {
                                pinHandle = pinnableContainer?.pin()
                                isPinned = true
                            }
                        },
                        colors =
                            if (isPinned) {
                                ButtonDefaults.buttonColors()
                            } else {
                                ButtonDefaults.filledTonalButtonColors()
                            },
                    ) {
                        Text(if (isPinned) "Unpin" else "Pin Off-screen")
                    }
                },
            )
        }
    }
}

TransformingLazyColumnWithSnapSample

@Preview
@Composable
fun TransformingLazyColumnWithSnapSample() {
    val transformationSpec = rememberTransformationSpec()
    val state = rememberTransformingLazyColumnState()
    TransformingLazyColumn(
        rotaryScrollableBehavior = RotaryScrollableDefaults.snapBehavior(scrollableState = state),
        flingBehavior = TransformingLazyColumnDefaults.snapFlingBehavior(state = state),
        modifier = Modifier.fillMaxWidth(),
        state = state,
        contentPadding = PaddingValues(20.dp),
    ) {
        items(count = 20) { index ->
            Button(
                modifier = Modifier.fillMaxWidth().transformedHeight(this, transformationSpec),
                transformation = SurfaceTransformation(transformationSpec),
                onClick = {},
            ) {
                Text(text = "Item $index")
            }
        }
    }
}

Last updated: