O NavDisplay oferece recursos de animação integrados para criar transições visuais
suaves enquanto os usuários navegam pelo app. É possível personalizar essas
animações globalmente para o NavDisplay ou no nível de Scene usando
metadados.
Entender os recursos de animação integrados
O NavDisplay usa a API ContentTransform para definir como o conteúdo é animado
durante a navegação. O NavDisplay anima automaticamente as transições entre
cenas quando uma chave derivada da classe da cena atual e a propriedade key
dela mudam. Quando essa chave muda, o NavDisplay usa o
ContentTransform para o tipo de transição (avançar, voltar ou voltar
com previsão) da cena adequada na transição. Se esse ContentTransform
não estiver definido, o NavDisplay vai usar a transição
padrão correspondente.
Substituir transições padrão
É possível substituir os comportamentos de animação padrão fornecendo parâmetros de transição
para NavDisplay.
transitionSpec: esse parâmetro define aContentTransforma ser aplicada quando o conteúdo é adicionado à backstack (ou seja, ao navegar para frente).popTransitionSpec: esse parâmetro define aContentTransforma ser aplicada quando o conteúdo é removido da backstack (ou seja, ao voltar na navegação).predictivePopTransitionSpec: esse parâmetro define oContentTransforma ser aplicado quando o conteúdo é removido usando um gesto de volta preditivo.
Substituir transições no nível Scene
É possível usar metadados para definir animações personalizadas para cenas individuais
usando as seguintes chaves de metadados definidas por NavDisplay:
NavDisplay.TransitionKey: a animação de navegação para frente.NavDisplay.PopTransitionKey: a animação de navegação para trás.NavDisplay.PredictivePopTransitionKey: a animação de volta preditiva.
Quando fornecidas, essas transições no nível da cena são usadas em vez dos
padrões correspondentes definidos no NavDisplay.
O snippet a seguir demonstra as transições globais de NavDisplay e uma
substituição no nível individual de 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) ) } } } }
Transição de entradas de navegação entre cenas
Em apps que criam layouts personalizados usando cenas, é possível que uma
NavEntry seja incluída na propriedade entries de ambas as cenas durante uma
transição. Internamente, o NavDisplay verifica se cada entrada é mostrada em,
no máximo, uma cena por vez, o que pode resultar em transições instáveis quando a
cena que renderiza um NavEntry muda. Para animar as entradas entre
cenas de forma suave, envolva o NavDisplay em um SharedTransitionLayout e
forneça o SharedTransitionScope ao NavDisplay, conforme mostrado no
exemplo a seguir:
SharedTransitionLayout { NavDisplay( // ... sharedTransitionScope = this ) }
SharedTransitionScope para NavDisplay.SharedTransitionScope para NavDisplay.