androidx.wear.compose.material3.lazy

Extension functions summary

Modifier

A modifier that enables Material3 Motion transformations for content within a TransformingLazyColumn item.

Modifier
@Composable
Modifier.scrollTransform(
    scope: TransformingLazyColumnItemScope,
    backgroundColor: Color,
    shape: Shape
)

A modifier that enables Material3 Motion transformations for content within a TransformingLazyColumn item.

Modifier
@Composable
Modifier.scrollTransform(
    scope: TransformingLazyColumnItemScope,
    shape: Shape,
    painter: Painter,
    border: BorderStroke?
)

A modifier that enables Material3 Motion transformations for content within a TransformingLazyColumn item.

Modifier

This modifier provides the height of the target composable to the scrollTransform during a morph transition and represents minimum height of the item when morphed.

Extension functions

@Composable
fun Modifier.scrollTransform(scope: TransformingLazyColumnItemScope): Modifier

A modifier that enables Material3 Motion transformations for content within a TransformingLazyColumn item.

This modifier calculates and applies transformations to the content and background based on the TransformingLazyColumnItemScrollProgress of the item inside the TransformingLazyColumnItemScope. It adjusts the height, position, applies scaling and morphing effects as the item scrolls.

Note that in most cases is recommended to use one of the other overrides to explicitly provide Shape and background Color (or Painter) so the modifier can do the background drawing and apply specific effects to background and content, as in the Material spec.

import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.unit.dp
import androidx.wear.compose.foundation.lazy.TransformingLazyColumn
import androidx.wear.compose.foundation.lazy.items
import androidx.wear.compose.foundation.lazy.rememberTransformingLazyColumnState
import androidx.wear.compose.material3.AppScaffold
import androidx.wear.compose.material3.EdgeButton
import androidx.wear.compose.material3.EdgeButtonSize
import androidx.wear.compose.material3.ListHeader
import androidx.wear.compose.material3.MaterialTheme
import androidx.wear.compose.material3.ScreenScaffold
import androidx.wear.compose.material3.ScreenScaffoldDefaults
import androidx.wear.compose.material3.Text
import androidx.wear.compose.material3.lazy.scrollTransform

val allIngredients = listOf("2 eggs", "tomato", "cheese", "bread")
val state = rememberTransformingLazyColumnState()
val coroutineScope = rememberCoroutineScope()
AppScaffold {
    ScreenScaffold(
        state,
        edgeButton = {
            EdgeButton(onClick = { coroutineScope.launch { state.scrollToItem(1) } }) {
                Text("To top")
            }
        }
    ) {
        TransformingLazyColumn(
            state = state,
            contentPadding =
                ScreenScaffoldDefaults.contentPaddingWithEdgeButton(
                    EdgeButtonSize.Small,
                    start = 10.dp,
                    end = 10.dp,
                    top = 20.dp,
                    extraBottom = 20.dp
                ),
            modifier = Modifier.background(MaterialTheme.colorScheme.background)
        ) {
            item(contentType = "header") {
                // No modifier is applied - no Material 3 Motion.
                ListHeader { Text("Ingredients") }
            }

            items(allIngredients, key = { it }) { ingredient ->
                Text(
                    ingredient,
                    color = MaterialTheme.colorScheme.onSurface,
                    style = MaterialTheme.typography.bodyLarge,
                    modifier =
                        Modifier.fillMaxWidth()
                            // Apply Material 3 Motion transformations.
                            .scrollTransform(
                                this,
                                backgroundColor = MaterialTheme.colorScheme.surfaceContainer,
                                shape = MaterialTheme.shapes.small
                            )
                            .padding(10.dp)
                )
            }
        }
    }
}
Parameters
scope: TransformingLazyColumnItemScope

The TransformingLazyColumnItemScope provides access to the item's index and key.

@Composable
fun Modifier.scrollTransform(
    scope: TransformingLazyColumnItemScope,
    backgroundColor: Color,
    shape: Shape = RectangleShape
): Modifier

A modifier that enables Material3 Motion transformations for content within a TransformingLazyColumn item. It also draws the background behind the content using Material3 Motion transformations.

This modifier calculates and applies transformations to the content based on the TransformingLazyColumnItemScrollProgress of the item inside the TransformingLazyColumn. It adjusts the height, position, applies scaling and morphing effects as the item scrolls.

import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.unit.dp
import androidx.wear.compose.foundation.lazy.TransformingLazyColumn
import androidx.wear.compose.foundation.lazy.items
import androidx.wear.compose.foundation.lazy.rememberTransformingLazyColumnState
import androidx.wear.compose.material3.AppScaffold
import androidx.wear.compose.material3.EdgeButton
import androidx.wear.compose.material3.EdgeButtonSize
import androidx.wear.compose.material3.ListHeader
import androidx.wear.compose.material3.MaterialTheme
import androidx.wear.compose.material3.ScreenScaffold
import androidx.wear.compose.material3.ScreenScaffoldDefaults
import androidx.wear.compose.material3.Text
import androidx.wear.compose.material3.lazy.scrollTransform

val allIngredients = listOf("2 eggs", "tomato", "cheese", "bread")
val state = rememberTransformingLazyColumnState()
val coroutineScope = rememberCoroutineScope()
AppScaffold {
    ScreenScaffold(
        state,
        edgeButton = {
            EdgeButton(onClick = { coroutineScope.launch { state.scrollToItem(1) } }) {
                Text("To top")
            }
        }
    ) {
        TransformingLazyColumn(
            state = state,
            contentPadding =
                ScreenScaffoldDefaults.contentPaddingWithEdgeButton(
                    EdgeButtonSize.Small,
                    start = 10.dp,
                    end = 10.dp,
                    top = 20.dp,
                    extraBottom = 20.dp
                ),
            modifier = Modifier.background(MaterialTheme.colorScheme.background)
        ) {
            item(contentType = "header") {
                // No modifier is applied - no Material 3 Motion.
                ListHeader { Text("Ingredients") }
            }

            items(allIngredients, key = { it }) { ingredient ->
                Text(
                    ingredient,
                    color = MaterialTheme.colorScheme.onSurface,
                    style = MaterialTheme.typography.bodyLarge,
                    modifier =
                        Modifier.fillMaxWidth()
                            // Apply Material 3 Motion transformations.
                            .scrollTransform(
                                this,
                                backgroundColor = MaterialTheme.colorScheme.surfaceContainer,
                                shape = MaterialTheme.shapes.small
                            )
                            .padding(10.dp)
                )
            }
        }
    }
}
Parameters
scope: TransformingLazyColumnItemScope

The TransformingLazyColumnItemScope provides access to the item's index and key.

backgroundColor: Color

Color of the background.

shape: Shape = RectangleShape

Shape of the background.

@Composable
fun Modifier.scrollTransform(
    scope: TransformingLazyColumnItemScope,
    shape: Shape,
    painter: Painter,
    border: BorderStroke? = null
): Modifier

A modifier that enables Material3 Motion transformations for content within a TransformingLazyColumn item.

This modifier calculates and applies transformations to the content and background based on the TransformingLazyColumnItemScrollProgress of the item inside the TransformingLazyColumnItemScope. It adjusts the height, position, applies scaling and morphing effects as the item scrolls.

import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.unit.dp
import androidx.wear.compose.foundation.lazy.TransformingLazyColumn
import androidx.wear.compose.foundation.lazy.items
import androidx.wear.compose.foundation.lazy.rememberTransformingLazyColumnState
import androidx.wear.compose.material3.AppScaffold
import androidx.wear.compose.material3.EdgeButton
import androidx.wear.compose.material3.EdgeButtonSize
import androidx.wear.compose.material3.ListHeader
import androidx.wear.compose.material3.MaterialTheme
import androidx.wear.compose.material3.ScreenScaffold
import androidx.wear.compose.material3.ScreenScaffoldDefaults
import androidx.wear.compose.material3.Text
import androidx.wear.compose.material3.lazy.scrollTransform

val allIngredients = listOf("2 eggs", "tomato", "cheese", "bread")
val state = rememberTransformingLazyColumnState()
val coroutineScope = rememberCoroutineScope()
AppScaffold {
    ScreenScaffold(
        state,
        edgeButton = {
            EdgeButton(onClick = { coroutineScope.launch { state.scrollToItem(1) } }) {
                Text("To top")
            }
        }
    ) {
        TransformingLazyColumn(
            state = state,
            contentPadding =
                ScreenScaffoldDefaults.contentPaddingWithEdgeButton(
                    EdgeButtonSize.Small,
                    start = 10.dp,
                    end = 10.dp,
                    top = 20.dp,
                    extraBottom = 20.dp
                ),
            modifier = Modifier.background(MaterialTheme.colorScheme.background)
        ) {
            item(contentType = "header") {
                // No modifier is applied - no Material 3 Motion.
                ListHeader { Text("Ingredients") }
            }

            items(allIngredients, key = { it }) { ingredient ->
                Text(
                    ingredient,
                    color = MaterialTheme.colorScheme.onSurface,
                    style = MaterialTheme.typography.bodyLarge,
                    modifier =
                        Modifier.fillMaxWidth()
                            // Apply Material 3 Motion transformations.
                            .scrollTransform(
                                this,
                                backgroundColor = MaterialTheme.colorScheme.surfaceContainer,
                                shape = MaterialTheme.shapes.small
                            )
                            .padding(10.dp)
                )
            }
        }
    }
}
Parameters
scope: TransformingLazyColumnItemScope

The TransformingLazyColumnItemScope provides access to the item's index and key.

shape: Shape

Shape of the background.

painter: Painter

Painter to use for the background.

border: BorderStroke? = null

Border to draw around the background, or null if no border is needed.

targetMorphingHeight

fun Modifier.targetMorphingHeight(scope: TransformingLazyColumnItemScope): Modifier

This modifier provides the height of the target composable to the scrollTransform during a morph transition and represents minimum height of the item when morphed.

Should be applied to a single child element or none at all (in which case, the morph effect is disabled). When applied to multiple child elements, the last placed child's height we be used for morphing.

import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.unit.dp
import androidx.wear.compose.foundation.lazy.TransformingLazyColumn
import androidx.wear.compose.foundation.lazy.items
import androidx.wear.compose.foundation.lazy.rememberTransformingLazyColumnState
import androidx.wear.compose.material3.AppScaffold
import androidx.wear.compose.material3.EdgeButton
import androidx.wear.compose.material3.EdgeButtonSize
import androidx.wear.compose.material3.ListHeader
import androidx.wear.compose.material3.MaterialTheme
import androidx.wear.compose.material3.ScreenScaffold
import androidx.wear.compose.material3.ScreenScaffoldDefaults
import androidx.wear.compose.material3.Text
import androidx.wear.compose.material3.lazy.scrollTransform
import androidx.wear.compose.material3.lazy.targetMorphingHeight

data class MenuItem(val title: String, val price: Float)

val drinks =
    listOf(
        MenuItem("Cappuccino", 2.5f),
        MenuItem("Late", 3f),
        MenuItem("Flat White", 3.2f),
        MenuItem("Americano", 1.5f),
        MenuItem("Black tea", 2f),
        MenuItem("London fog", 2.6f),
    )
val state = rememberTransformingLazyColumnState()
val coroutineScope = rememberCoroutineScope()
AppScaffold {
    ScreenScaffold(
        state,
        edgeButton = {
            EdgeButton(
                onClick = {
                    coroutineScope.launch {
                        // Scroll to the first non-header item.
                        state.scrollToItem(1)
                    }
                }
            ) {
                Text("To top")
            }
        }
    ) {
        TransformingLazyColumn(
            state = state,
            contentPadding =
                ScreenScaffoldDefaults.contentPaddingWithEdgeButton(
                    EdgeButtonSize.Medium,
                    start = 10.dp,
                    end = 10.dp
                ),
            modifier = Modifier.background(MaterialTheme.colorScheme.background),
        ) {
            item(contentType = "header") {
                // No modifier is applied - no Material 3 Motion transformations.
                ListHeader { Text("Drinks", style = MaterialTheme.typography.labelLarge) }
            }
            items(drinks, key = { it.title }) { notification ->
                Column(
                    modifier =
                        Modifier.fillMaxWidth()
                            // Apply Material 3 Motion effect.
                            .scrollTransform(
                                this@items,
                                backgroundColor = Color.DarkGray,
                                shape = RoundedCornerShape(20.dp),
                            )
                            .padding(horizontal = 10.dp)
                ) {
                    Text(
                        notification.title,
                        fontWeight = FontWeight.Bold,
                        style = MaterialTheme.typography.labelLarge,
                        // Morphing is focusing on the title.
                        modifier = Modifier.targetMorphingHeight(this@items)
                    )
                    // Price is revealed after the morph.
                    Text("$${notification.price}")
                }
            }
        }
    }
}
Parameters
scope: TransformingLazyColumnItemScope

The TransformingLazyColumnItemScope provides access to the item's index and key.