NavDisplay는 사용자가 앱을 탐색할 때 원활한 시각적 전환을 만들 수 있는 내장 애니메이션 기능을 제공합니다. 메타데이터를 사용하여 NavDisplay에 대해 전역적으로 또는 Scene 수준에서 이러한 애니메이션을 맞춤설정할 수 있습니다.
기본 제공 애니메이션 기능 이해
NavDisplay는 ContentTransform API를 사용하여 탐색 중에 콘텐츠가 애니메이션 처리되는 방식을 정의합니다. 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 ) }