ב-NavDisplay יש יכולות אנימציה מובנות שמאפשרות ליצור מעברים חזותיים חלקים כשהמשתמשים מנווטים באפליקציה. אפשר להתאים אישית את האנימציות האלה באופן גלובלי ל-NavDisplay או ברמת Scene באמצעות מטא-נתונים.
הסבר על יכולות האנימציה המובנות
NavDisplay משתמש ב-API של ContentTransform כדי להגדיר את האנימציה של התוכן במהלך הניווט. NavDisplay יוצר אנימציה אוטומטית של מעברים בין סצנות כשמפתח שנגזר מהמחלקה של הסצנה הנוכחית והמאפיין key שלה משתנה. כשהמפתח הזה משתנה, NavDisplay משתמש ב-ContentTransform לסוג המעבר – קדימה, אחורה או חיזוי החזרה – מהסצנה המתאימה במעבר. אם לא מגדירים את ContentTransform, NavDisplay משתמש במעבר ברירת המחדל המתאים.
שינוי המעברים שמוגדרים כברירת מחדל
אפשר לשנות את התנהגויות ברירת המחדל של האנימציה על ידי הוספת פרמטרים של מעבר ל-NavDisplay.
-
transitionSpec: הפרמטר הזה מגדיר את ה-ContentTransformשצריך להחיל כשתוכן נוסף למקבץ הפעילויות הקודמות (כלומר, כשמנווטים קדימה). -
popTransitionSpec: הפרמטר הזה מגדיר את ה-ContentTransformשצריך להחיל כשתוכן מוסר ממקבץ הפעילויות הקודמות (כלומר, כשמנווטים אחורה). -
predictivePopTransitionSpec: הפרמטר הזה מגדיר את ה-ContentTransformשצריך להפעיל כשתוכן מוקפץ באמצעות חיזוי תנועת החזרה.
שינוי המעברים ברמת Scene
אתם יכולים להשתמש במטא-נתונים כדי להגדיר אנימציות בהתאמה אישית לסצנות ספציפיות באמצעות מפתחות המטא-נתונים הבאים שמוגדרים על ידי NavDisplay:
-
NavDisplay.TransitionKey: האנימציה של הניווט קדימה. -
NavDisplay.PopTransitionKey: האנימציה של הניווט אחורה. -
NavDisplay.PredictivePopTransitionKey: האנימציה של חיזוי החזרה.
אם מספקים את המעברים האלה ברמת הסצנה, המערכת משתמשת בהם במקום בערכי ברירת המחדל התואמים שמוגדרים ב-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 = metadata { put(NavDisplay.TransitionKey) { // Slide new content up, keeping the old content in place underneath slideInVertically( initialOffsetY = { it }, animationSpec = tween(1000) ) togetherWith ExitTransition.KeepUntilTransitionsFinished } put(NavDisplay.PopTransitionKey) { // Slide old content down, revealing the new content in place underneath EnterTransition.None togetherWith slideOutVertically( targetOffsetY = { it }, animationSpec = tween(1000) ) } put(NavDisplay.PredictivePopTransitionKey) { // 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) ) } } } }
מעבר בין רשומות ניווט בין סצנות
באפליקציות שיוצרות פריסות בהתאמה אישית באמצעות סצנות, יכול להיות ש-NavEntry ייכלל במאפיין entries של שתי הסצנות במהלך מעבר. באופן פנימי, NavDisplay מוודא שכל רשומה מוצגת בסצנה אחת לכל היותר בכל זמן נתון, מה שעלול לגרום למעברים קופצניים כשהסצנה שמעבדת NavEntry משתנה. כדי להוסיף אנימציה חלקה לרשומות בין סצנות, אפשר לעטוף את NavDisplay ב-SharedTransitionLayout ולספק את SharedTransitionScope ל-NavDisplay, כמו בדוגמה הבאה:
SharedTransitionLayout { NavDisplay( // ... sharedTransitionScope = this ) }
SharedTransitionScope אל NavDisplay.SharedTransitionScope ל-NavDisplay.