NavDisplay ma wbudowane funkcje animacji, które umożliwiają tworzenie płynnych przejść wizualnych podczas poruszania się użytkowników po aplikacji. Możesz dostosować te animacje globalnie dla NavDisplay lub na poziomie Scene za pomocą metadanych.
Poznaj wbudowane funkcje animacji
NavDisplay korzysta z interfejsu ContentTransform API, aby określić, jak treść jest animowana podczas nawigacji. NavDisplay automatycznie animuje przejścia między scenami, gdy zmienia się klucz pochodzący z klasy bieżącej sceny i jej key
właściwości. Gdy ten klucz się zmieni, NavDisplay użyje ContentTransform dla typu przejścia – do przodu, do tyłu lub przewidywanego przejścia wstecz – z odpowiedniej sceny w przejściu. Jeśli ContentTransform nie jest zdefiniowany, NavDisplay wraca do używania odpowiedniego domyślnego przejścia.
Zastępowanie domyślnych przejść
Możesz zastąpić domyślne działanie animacji, podając parametry przejścia do funkcji NavDisplay.
transitionSpec: ten parametr określaContentTransform, które ma być zastosowane, gdy treść jest dodawana do stosu wstecznego (czyli podczas przechodzenia do przodu).popTransitionSpec: ten parametr określaContentTransform, który ma być stosowany, gdy treść jest usuwana z listy wstecznej (czyli podczas nawigacji wstecz).predictivePopTransitionSpec: ten parametr określaContentTransform, który ma być stosowany, gdy treść jest wysuwana za pomocą gestu przewidywania powrotu.
Zastępowanie przejść na poziomie Scene
Za pomocą metadanych możesz zdefiniować niestandardowe animacje dla poszczególnych scen, używając tych kluczy metadanych zdefiniowanych przez NavDisplay:
NavDisplay.TransitionKey: animacja nawigacji do przodu.NavDisplay.PopTransitionKey: animacja nawigacji wstecz.NavDisplay.PredictivePopTransitionKey: animacja przewidywanego przejścia wstecz.
Jeśli są dostępne, te przejścia na poziomie sceny są używane zamiast odpowiednich ustawień domyślnych skonfigurowanych w NavDisplay.
Poniższy fragment kodu pokazuje zarówno globalne przejścia NavDisplay, jak i zastąpienie na poziomie poszczególnych elementów 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) ) } } } }
Przenoszenie wpisów nawigacyjnych między scenami
W aplikacjach, które tworzą niestandardowe układy za pomocą scen, podczas przejścia może się zdarzyć, że element
NavEntry będzie uwzględniony we właściwości entries obu scen. Wewnętrznie NavDisplay sprawdza, czy każdy wpis jest wyświetlany w maksymalnie jednej scenie w danym momencie, co może powodować skokowe przejścia, gdy zmienia się scena renderująca NavEntry. Aby płynnie animować przejścia między scenami, możesz umieścić element NavDisplay w znaczniku SharedTransitionLayout i przekazać element SharedTransitionScope do elementu NavDisplay, jak pokazano w tym przykładzie:
SharedTransitionLayout { NavDisplay( // ... sharedTransitionScope = this ) }