Lists with Compose for Wear OS

Lists let users select an item from a set of choices on Wear OS devices.

Many Wear OS devices use round screens, which makes it more difficult to see list items that appear near the top and bottom of the screen. For this reason, Compose for Wear OS includes a version of the LazyColumn class called ScalingLazyColumn, which supports scaling and fading effects. When items move toward the center of the screen, they get larger and more opaque.

The following animation shows how an element's size and transparency changes as it moves along the screen:

The following code snippet shows how to create a list that contains text for each item:

val contentModifier = Modifier
    .fillMaxWidth()
    .padding(bottom = 8.dp)

@Composable
fun WearApp() {
    WearAppTheme {
        // Hoist the list state to remember scroll position across compositions.
        val listState = rememberScalingLazyListState()

        ScalingLazyColumn(
            modifier = Modifier.fillMaxSize(),
            autoCentering = AutoCenteringParams(itemIndex = 0),
            state = listState
        ) {
            item { TextItem(contentModifier, stringResource(R.string.first)) }
            item { TextItem(contentModifier, stringResource(R.string.second)) }
        }
    }
}

@Composable
fun TextItem(modifier: Modifier = Modifier, contents: String) {
    Text(
        modifier = modifier,
        textAlign = TextAlign.Center,
        text = contents
    )
}

Add a snap-and-fling effect

You can add a snap-and-fling behavior to finger gestures that the user applies to ScalingLazyColumn objects. This effect helps users more precisely navigate through the items in a list while also helping them move more quickly through a long list.

To add this effect to a list or picker in your app, include the flingBehavior parameter in your ScalingLazyColumn definition, as shown in the following code snippet:

ScalingLazyColumn(
    modifier = modifier ...,
    flingBehavior = ScalingLazyColumnDefaults.snapFlingBehavior(
        state = listState,
        snapOffset = 0
        // Exponential decay by default. You can also explicitly define a
        // DecayAnimationSpec.
    ) {
        // Contents of the list here.
}

To apply similar snap-and-fling behavior to a ScalingLazyColumn when the user interacts with a rotary dial, use RotaryWithSnap, available in Horologist on GitHub.