Menganimasikan transisi antar-tujuan

NavDisplay menyediakan kemampuan animasi bawaan untuk membuat transisi visual yang lancar saat pengguna menjelajahi aplikasi Anda. Anda dapat menyesuaikan animasi ini secara global untuk NavDisplay atau per NavEntry menggunakan metadata.

Mengganti transisi default

NavDisplay menggunakan ContentTransform untuk menentukan cara animasi konten selama navigasi. Anda dapat mengganti perilaku animasi default dengan memberikan parameter transisi ke NavDisplay.

  • transitionSpec: Parameter ini menentukan ContentTransform yang akan diterapkan saat konten ditambahkan ke data sebelumnya (yaitu, saat menavigasi ke depan).
  • popTransitionSpec: Parameter ini menentukan ContentTransform yang akan diterapkan saat konten dihapus dari data sebelumnya (yaitu, saat kembali ke layar sebelumnya).
  • predictivePopTransitionSpec: Parameter ini menentukan ContentTransform yang akan diterapkan saat konten muncul menggunakan gestur kembali prediktif.

Mengganti transisi di setiap tingkat NavEntry

Anda juga dapat menentukan animasi kustom untuk NavEntry tertentu menggunakan metadata-nya. NavDisplay mengenali kunci metadata khusus untuk menerapkan transisi per entri:

  • NavDisplay.transitionSpec: Gunakan fungsi helper ini untuk menentukan animasi navigasi maju.
  • NavDisplay.popTransitionSpec: Gunakan fungsi bantuan ini untuk menentukan animasi navigasi mundur untuk NavEntry tertentu.
  • NavDisplay.predictivePopTransitionSpec: Gunakan fungsi bantuan ini untuk menentukan animasi untuk gestur kembali prediktif untuk NavEntry tertentu.

Transisi metadata per entri ini menggantikan transisi global NavDisplay dengan nama yang sama.

Cuplikan berikut menunjukkan transisi NavDisplay global dan penggantian di setiap tingkat NavEntry:

@Serializable
data object ScreenA : NavKey

@Serializable
data object ScreenB : NavKey

@Serializable
data object ScreenC : NavKey

class AnimatedNavDisplayActivity : ComponentActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContent {

            Scaffold { paddingValues ->

                val backStack = rememberNavBackStack(ScreenA)

                NavDisplay(
                    backStack = backStack,
                    onBack = { backStack.removeLastOrNull() },
                    entryProvider = entryProvider {
                        entry<ScreenA> {
                            ContentOrange("This is Screen A") {
                                Button(onClick = { backStack.add(ScreenB) }) {
                                    Text("Go to Screen B")
                                }
                            }
                        }
                        entry<ScreenB> {
                            ContentMauve("This is Screen B") {
                                Button(onClick = { backStack.add(ScreenC) }) {
                                    Text("Go to Screen C")
                                }
                            }
                        }
                        entry<ScreenC>(
                            metadata = NavDisplay.transitionSpec {
                                // Slide new content up, keeping the old content in place underneath
                                slideInVertically(
                                    initialOffsetY = { it },
                                    animationSpec = tween(1000)
                                ) togetherWith ExitTransition.KeepUntilTransitionsFinished
                            } + NavDisplay.popTransitionSpec {
                                // Slide old content down, revealing the new content in place underneath
                                EnterTransition.None togetherWith
                                    slideOutVertically(
                                        targetOffsetY = { it },
                                        animationSpec = tween(1000)
                                    )
                            } + NavDisplay.predictivePopTransitionSpec {
                                // Slide old content down, revealing the new content in place underneath
                                EnterTransition.None togetherWith
                                    slideOutVertically(
                                        targetOffsetY = { it },
                                        animationSpec = tween(1000)
                                    )
                            }
                        ) {
                            ContentGreen("This is Screen C")
                        }
                    },
                    transitionSpec = {
                        // Slide in from right when navigating forward
                        slideInHorizontally(initialOffsetX = { it }) togetherWith
                            slideOutHorizontally(targetOffsetX = { -it })
                    },
                    popTransitionSpec = {
                        // Slide in from left when navigating back
                        slideInHorizontally(initialOffsetX = { -it }) togetherWith
                            slideOutHorizontally(targetOffsetX = { it })
                    },
                    predictivePopTransitionSpec = {
                        // Slide in from left when navigating back
                        slideInHorizontally(initialOffsetX = { -it }) togetherWith
                            slideOutHorizontally(targetOffsetX = { it })
                    },
                    modifier = Modifier.padding(paddingValues)
                )
            }
        }
    }
}

Gambar 1. Aplikasi dengan animasi kustom.