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 は、すべてのエントリが常に最大 1 つのシーンに表示されることを検証します。これにより、NavEntry をレンダリングするシーンが変更されたときに、トランジションがジャンプすることがあります。シーン間のエントリをスムーズにアニメーション化するには、次の例に示すように、NavDisplay を SharedTransitionLayout でラップし、NavDisplay に SharedTransitionScope を指定します。
SharedTransitionLayout { NavDisplay( // ... sharedTransitionScope = this ) }