NavDisplay offre funzionalità di animazione integrate per creare transizioni visive fluide mentre gli utenti navigano nell'app. Puoi personalizzare queste animazioni a livello globale per NavDisplay o a livello di Scene utilizzando i metadati.
Comprendere le funzionalità di animazione integrate
NavDisplay utilizza l'API ContentTransform per definire l'animazione dei contenuti
durante la navigazione. NavDisplay anima automaticamente le transizioni tra le
scene quando cambia una chiave derivata dalla classe della scena corrente e dalla relativa proprietà key. Quando questa chiave cambia, NavDisplay utilizza
ContentTransform per il tipo di transizione (avanti, indietro o indietro predittivo) dalla scena appropriata della transizione. Se ContentTransform
non è definito, NavDisplay utilizza la transizione
predefinita corrispondente.
Sostituisci le transizioni predefinite
Puoi ignorare i comportamenti di animazione predefiniti fornendo parametri di transizione a NavDisplay.
transitionSpec: questo parametro definisce la transizioneContentTransformda applicare quando i contenuti vengono aggiunti allo stack precedente (ovvero quando si naviga in avanti).popTransitionSpec: questo parametro definisce laContentTransformda applicare quando i contenuti vengono rimossi dallo stack precedente (ovvero quando si torna indietro).predictivePopTransitionSpec: questo parametro definisce l'ContentTransformda applicare quando i contenuti vengono visualizzati utilizzando un gesto di indietro predittivo.
Ignorare le transizioni a livello di Scene
Puoi utilizzare i metadati per definire animazioni personalizzate per le singole scene
utilizzando le seguenti chiavi dei metadati definite da NavDisplay:
NavDisplay.TransitionKey: l'animazione di navigazione in avanti.NavDisplay.PopTransitionKey: l'animazione di navigazione all'indietro.NavDisplay.PredictivePopTransitionKey: l'animazione predittiva per Indietro.
Se fornite, queste transizioni a livello di scena vengono utilizzate al posto dei valori predefiniti corrispondenti impostati in NavDisplay.
Lo snippet seguente mostra sia le transizioni globali di NavDisplay sia un
override a livello di singolo 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) ) } } } }
Transizione delle voci di navigazione tra le scene
Nelle app che creano layout personalizzati utilizzando le scene, è possibile che un
NavEntry venga incluso nella proprietà entries di entrambe le scene durante una
transizione. A livello interno, NavDisplay verifica che ogni voce venga visualizzata in
al massimo una scena alla volta, il che può comportare transizioni instabili quando
la scena che esegue il rendering di un NavEntry cambia. Per animare in modo fluido le voci tra le scene, puoi racchiudere NavDisplay in un SharedTransitionLayout e fornire SharedTransitionScope a NavDisplay come mostrato nell'esempio seguente:
SharedTransitionLayout { NavDisplay( // ... sharedTransitionScope = this ) }