androidx.wear.compose.navigation3

Classes

SwipeDismissableSceneStrategy

A SceneStrategy that displays entries within a Wear Material component.

Top-level functions summary

Top-level functions

rememberSwipeDismissableSceneStrategy

@Composable
fun <T : Any> rememberSwipeDismissableSceneStrategy(
    isUserSwipeEnabled: Boolean = true
): SwipeDismissableSceneStrategy<T>

Creates and remembers a SwipeDismissableSceneStrategy.

Example of a androidx.navigation3.ui.NavDisplay with SwipeDismissableSceneStrategy alternating between list and detail entries:

import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
import androidx.compose.runtime.remember
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.navigation3.runtime.NavKey
import androidx.navigation3.runtime.entryProvider
import androidx.navigation3.runtime.rememberNavBackStack
import androidx.navigation3.ui.NavDisplay
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.Button
import androidx.wear.compose.material3.Card
import androidx.wear.compose.material3.EdgeButton
import androidx.wear.compose.material3.ListHeader
import androidx.wear.compose.material3.ScreenScaffold
import androidx.wear.compose.material3.SurfaceTransformation
import androidx.wear.compose.material3.Text
import androidx.wear.compose.material3.TitleCard
import androidx.wear.compose.material3.lazy.rememberTransformationSpec
import androidx.wear.compose.material3.lazy.transformedHeight
import androidx.wear.compose.navigation3.rememberSwipeDismissableSceneStrategy

// Example of using a NavDisplay with SwipeDismissableSceneStrategy for list-detail navigation.

// Strongly-typed, serializable navigation destinations are defined at global scope as follows:
// @Serializable object NotificationList : NavKey
// @Serializable data class NotificationDetail(val id: Int) : NavKey

// NotificationItem needs to be defined at top-level or class-level to ensure stability in
// Compose:
// data class NotificationItem(val id: Int, val title: String, val body: String)
val backStack = rememberNavBackStack(NotificationList)

val notifications = remember {
    listOf(
        NotificationItem(
            0,
            "☕ Coffee Break? Grab a pick-me-up",
            "Step away from the screen and grab a pick-me-up. Step away from the screen and grab a pick-me-up.",
        ),
        NotificationItem(
            1,
            "🌟 You're Awesome!",
            "Just a little reminder in case you forgot 😊",
        ),
        NotificationItem(
            2,
            "👀 Did you know our latest feature?",
            "Check out [app name]'s latest feature update.",
        ),
        NotificationItem(
            3,
            "📅 Appointment Time In 15 Minutes",
            "Your meeting with [name] is in 15 minutes.",
        ),
    )
}

NavDisplay(
    backStack = backStack,
    sceneStrategy = rememberSwipeDismissableSceneStrategy(),
    entryProvider =
        entryProvider {
            entry<NotificationList> {
                val state = rememberTransformingLazyColumnState()
                val transformationSpec = rememberTransformationSpec()
                ScreenScaffold(
                    state,
                    edgeButton = { EdgeButton(onClick = onExit) { Text("Exit") } },
                ) { contentPadding ->
                    TransformingLazyColumn(state = state, contentPadding = contentPadding) {
                        item {
                            ListHeader(
                                transformation = SurfaceTransformation(transformationSpec),
                                modifier =
                                    Modifier.transformedHeight(this, transformationSpec)
                                        .animateItem(),
                            ) {
                                Text("Notifications")
                            }
                        }
                        items(notifications) { notification ->
                            Card(
                                onClick = {
                                    backStack.add(NotificationDetail(notification.id))
                                },
                                transformation = SurfaceTransformation(transformationSpec),
                                modifier =
                                    Modifier.fillMaxWidth()
                                        .transformedHeight(this, transformationSpec)
                                        .animateItem(),
                            ) {
                                Text(notification.title)
                            }
                        }
                    }
                }
            }

            entry<NotificationDetail> { key ->
                val item = requireNotNull(notifications.find { item -> item.id == key.id })
                ScreenScaffold { contentPadding ->
                    Box(
                        Modifier.fillMaxSize().padding(contentPadding),
                        contentAlignment = Alignment.Center,
                    ) {
                        TitleCard(title = { Text(item.title) }, content = { Text(item.body) })
                    }
                }
            }
        },
)

Example of a androidx.navigation3.ui.NavDisplay with SwipeDismissableSceneStrategy and on back behavior:

import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.height
import androidx.compose.runtime.mutableIntStateOf
import androidx.compose.runtime.remember
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.unit.dp
import androidx.navigation3.runtime.NavKey
import androidx.navigation3.runtime.entryProvider
import androidx.navigation3.runtime.rememberNavBackStack
import androidx.navigation3.ui.NavDisplay
import androidx.wear.compose.material3.Button
import androidx.wear.compose.material3.Text
import androidx.wear.compose.navigation3.rememberSwipeDismissableSceneStrategy

// Example of using a NavDisplay with SwipeDismissableSceneStrategy and on back behavior.

// Strongly-typed, serializable navigation destinations are defined at global scope as follows:
// @Serializable object First: NavKey
// @Serializable object Second: NavKey
val backStack = rememberNavBackStack(First)

var swipedBackCount by remember { mutableIntStateOf(0) }

NavDisplay(
    backStack = backStack,
    onBack = {
        swipedBackCount++
        backStack.removeLastOrNull()
    },
    sceneStrategy = rememberSwipeDismissableSceneStrategy(),
    entryProvider =
        entryProvider {
            entry<First> {
                Column(
                    modifier = Modifier.fillMaxSize(),
                    horizontalAlignment = Alignment.CenterHorizontally,
                    verticalArrangement = Arrangement.Center,
                ) {
                    Text("First")
                    Spacer(modifier = Modifier.height(16.dp))
                    Button(onClick = { backStack.add(Second) }) { Text("Second") }

                    Spacer(modifier = Modifier.height(16.dp))
                    Text("Swiped back $swipedBackCount times")
                }
            }
            entry<Second> {
                Box(modifier = Modifier.fillMaxSize(), contentAlignment = Alignment.Center) {
                    Text("Second")
                }
            }
        },
)
Parameters
<T : Any>

the type of the backstack key

isUserSwipeEnabled: Boolean = true

Boolean Whether swipe-to-dismiss gesture is enabled.