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 でラップし、SharedTransitionScope を NavDisplay に指定します。
SharedTransitionLayout { NavDisplay( // ... sharedTransitionScope = this ) }
SharedTransitionScope を NavDisplay に渡さない場合のトランジションの途切れ。SharedTransitionScope を NavDisplay に渡す場合のスムーズなトランジション。