הנפשה בין יעדים

NavDisplay מספק יכולות אנימציה מובנות ליצירת מעברים חזותיים חלקים כשהמשתמשים מנווטים באפליקציה. אפשר להתאים אישית את האנימציות האלה באופן גלובלי עבור NavDisplay או על בסיס NavEntry ספציפי באמצעות מטא-נתונים.

שינוי של מעברי ברירת המחדל

NavDisplay משתמש בתגים ContentTransform כדי להגדיר את אופן האנימציה של התוכן במהלך הניווט. כדי לשנות את התנהגויות ברירת המחדל של האנימציה, אפשר לספק פרמטרים של מעבר ל-NavDisplay.

  • transitionSpec: הפרמטר הזה מגדיר את הערך של ContentTransform שיחול כשתווסף תוכן ל-back stack (כלומר, כשמנווטים קדימה).
  • 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. אפליקציה עם אנימציות בהתאמה אישית.