為目的地之間的轉場加上動畫效果

NavDisplay 提供內建動畫功能,可在使用者瀏覽應用程式時,建立流暢的視覺轉場效果。您可以使用中繼資料,為 NavDisplay 或個別 NavEntry 全域自訂這些動畫。

覆寫預設轉場效果

NavDisplay 會使用 ContentTransform 定義導覽期間的內容動畫效果。您可以為 NavDisplay 提供轉場參數,覆寫預設動畫行為。

  • transitionSpec:這個參數會定義在將內容新增至返回堆疊 (也就是前進導覽時) 時要套用的 ContentTransform
  • popTransitionSpec:這個參數會定義從返回堆疊中移除內容 (也就是返回時) 時要套用的 ContentTransform
  • predictivePopTransitionSpec:這個參數會定義使用預測返回手勢彈出內容時要套用的 ContentTransform

在個別 NavEntry 層級覆寫轉場

您也可以使用特定 NavEntry 的中繼資料,為其定義自訂動畫。NavDisplay 會辨識特殊中繼資料鍵,以便套用每個項目的轉場效果:

  • NavDisplay.transitionSpec:請使用這個輔助函式定義前向導覽動畫。
  • NavDisplay.popTransitionSpec:請使用這個輔助函式,為特定 NavEntry 定義向後導覽動畫。
  • NavDisplay.predictivePopTransitionSpec:使用這個輔助函式,為特定 NavEntry 定義預測返回手勢的動畫。

這些個別項目中繼資料轉換會覆寫 NavDisplay 的相同名稱全域轉換。

下列程式碼片段示範全域 NavDisplay 轉場效果,以及個別 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)
                )
            }
        }
    }
}

圖 1。應用程式顯示自訂動畫。