CoordinatorLayout
は、複雑な重複するネストされたレイアウトを可能にする ViewGroup
です。ツールバーやボトムシートの開閉など、内部に含まれるビューに対して特定のマテリアル デザインのインタラクションを有効にするためのコンテナとして使用されます。
Compose では、CoordinatorLayout
に最も近い同等物は Scaffold
です。Scaffold
は、マテリアル コンポーネントを一般的な画面パターンとインタラクションに組み合わせるためのコンテンツ スロットを提供します。このページでは、Compose で Scaffold
を使用するように CoordinatorLayout
実装を移行する方法について説明します。
移行手順
CoordinatorLayout
を Scaffold
に移行する手順は次のとおりです。
次のスニペットでは、
CoordinatorLayout
にToolBar
、ViewPager
、FloatingActionButton
を含むAppBarLayout
が含まれています。UI 階層からCoordinatorLayout
とその子をコメントアウトし、代わりにComposeView
を追加します。<!-- <androidx.coordinatorlayout.widget.CoordinatorLayout--> <!-- android:id="@+id/coordinator_layout"--> <!-- android:layout_width="match_parent"--> <!-- android:layout_height="match_parent"--> <!-- android:fitsSystemWindows="true">--> <!-- <androidx.compose.ui.platform.ComposeView--> <!-- android:id="@+id/compose_view"--> <!-- android:layout_width="match_parent"--> <!-- android:layout_height="match_parent"--> <!-- app:layout_behavior="@string/appbar_scrolling_view_behavior" />--> <!-- <com.google.android.material.appbar.AppBarLayout--> <!-- android:id="@+id/app_bar_layout"--> <!-- android:layout_width="match_parent"--> <!-- android:layout_height="wrap_content"--> <!-- android:fitsSystemWindows="true"--> <!-- android:theme="@style/Theme.Sunflower.AppBarOverlay">--> <!-- AppBarLayout contents here --> <!-- </com.google.android.material.appbar.AppBarLayout>--> <!-- </androidx.coordinatorlayout.widget.CoordinatorLayout>--> <androidx.compose.ui.platform.ComposeView android:id="@+id/compose_view" android:layout_width="match_parent" android:layout_height="match_parent" />
フラグメントまたはアクティビティで、追加した
ComposeView
への参照を取得し、その上でsetContent
メソッドを呼び出します。メソッドの本体で、コンテンツとしてScaffold
を設定します。composeView.setContent { Scaffold(Modifier.fillMaxSize()) { contentPadding -> // Scaffold contents // ... } }
Scaffold
のコンテンツに、画面のメイン コンテンツを追加します。上記の XML の主なコンテンツはViewPager2
であるため、Compose の同等物であるHorizontalPager
を使用します。Scaffold
のcontent
ラムダは、コンテンツ ルートに適用するPaddingValues
のインスタンスも受け取ります。Modifier.padding
を使用して、同じPaddingValues
をHorizontalPager
に適用できます。composeView.setContent { Scaffold(Modifier.fillMaxSize()) { contentPadding -> val pagerState = rememberPagerState { 10 } HorizontalPager( state = pagerState, modifier = Modifier.padding(contentPadding) ) { /* Page contents */ } } }
Scaffold
が提供する他のコンテンツ スロットを使用して、画面要素を追加し、残りの子ビューを移行します。topBar
スロットを使用してTopAppBar
を追加し、floatingActionButton
スロットを使用してFloatingActionButton
を指定できます。composeView.setContent { Scaffold( Modifier.fillMaxSize(), topBar = { TopAppBar( title = { Text("My App") } ) }, floatingActionButton = { FloatingActionButton( onClick = { /* Handle click */ } ) { Icon( Icons.Filled.Add, contentDescription = "Add Button" ) } } ) { contentPadding -> val pagerState = rememberPagerState { 10 } HorizontalPager( state = pagerState, modifier = Modifier.padding(contentPadding) ) { /* Page contents */ } } }
一般的なユースケース
ツールバーを折りたたむ、展開する
ビューシステムで CoordinatorLayout
を使用してツールバーを閉じたり開いたりするには、ツールバーのコンテナとして AppBarLayout
を使用します。次に、関連するスクロール可能なビュー(RecyclerView
や NestedScrollView
など)の XML で layout_behavior
を使用して Behavior
を指定し、スクロール時のツールバーの開閉方法を宣言します。
Compose では、TopAppBarScrollBehavior
を使用して同様の効果を実現できます。たとえば、スクロールアップ時にツールバーが表示されるように、折りたたみ/展開ツールバーを実装する手順は次のとおりです。
TopAppBarDefaults.enterAlwaysScrollBehavior()
を呼び出してTopAppBarScrollBehavior
を作成します。- 作成した
TopAppBarScrollBehavior
をTopAppBar
に指定します。 スクロール可能なコンテンツが上下にスクロールするときに、Scaffold がネストされたスクロール イベントを受信できるように、
Scaffold
のModifier.nestedScroll
を介してNestedScrollConnection
を接続します。これにより、コンテンツのスクロールに応じて、含まれるアプリバーを適切に開いたり閉じたりできます。// 1. Create the TopAppBarScrollBehavior val scrollBehavior = TopAppBarDefaults.enterAlwaysScrollBehavior() Scaffold( topBar = { TopAppBar( title = { Text("My App") }, // 2. Provide scrollBehavior to TopAppBar scrollBehavior = scrollBehavior ) }, // 3. Connect the scrollBehavior.nestedScrollConnection to the Scaffold modifier = Modifier .fillMaxSize() .nestedScroll(scrollBehavior.nestedScrollConnection) ) { contentPadding -> /* Contents */ // ... }
スクロールの収縮/拡大効果をカスタマイズする
enterAlwaysScrollBehavior
に複数のパラメータを指定して、折りたたみ/展開アニメーション効果をカスタマイズできます。TopAppBarDefaults
には、コンテンツが最後までスクロールされた場合にのみアプリバーを展開する exitUntilCollapsedScrollBehavior
などの他の TopAppBarScrollBehavior
も用意されています。
完全にカスタムの効果(パララックス エフェクトなど)を作成するには、独自の NestedScrollConnection
を作成し、コンテンツのスクロールに合わせてツールバーを手動でオフセットすることもできます。コードサンプルについては、AOSP のネストされたスクロール サンプルをご覧ください。
ドロワー
ビューを使用する場合は、DrawerLayout
をルートビューとして使用してナビゲーション ドロワーを実装します。CoordinatorLayout
は DrawerLayout
の子ビューです。DrawerLayout
には、引き出しにナビゲーション オプションを表示する NavigationView
などの別の子ビューも含まれています。
Compose では、ModalNavigationDrawer
コンポーザブルを使用してナビゲーション ドロワーを実装できます。ModalNavigationDrawer
は、ドロワー用の drawerContent
スロットと、画面のコンテンツ用の content
スロットを提供します。
ModalNavigationDrawer( drawerContent = { ModalDrawerSheet { Text("Drawer title", modifier = Modifier.padding(16.dp)) HorizontalDivider() NavigationDrawerItem( label = { Text(text = "Drawer Item") }, selected = false, onClick = { /*TODO*/ } ) // ...other drawer items } } ) { Scaffold(Modifier.fillMaxSize()) { contentPadding -> // Scaffold content // ... } }
詳細については、引き出しをご覧ください。
スナックバー
Scaffold
は snackbarHost
スロットを提供します。これは、Snackbar
を表示する SnackbarHost
コンポーザブルを受け入れることができます。
val scope = rememberCoroutineScope() val snackbarHostState = remember { SnackbarHostState() } Scaffold( snackbarHost = { SnackbarHost(hostState = snackbarHostState) }, floatingActionButton = { ExtendedFloatingActionButton( text = { Text("Show snackbar") }, icon = { Icon(Icons.Filled.Image, contentDescription = "") }, onClick = { scope.launch { snackbarHostState.showSnackbar("Snackbar") } } ) } ) { contentPadding -> // Screen content // ... }
詳しくは、スナックバーをご覧ください。
詳細
CoordinatorLayout
を Compose に移行する方法について詳しくは、次のリソースをご覧ください。
- マテリアル コンポーネントとレイアウト: Compose でサポートされているマテリアル デザイン コンポーネント(
Scaffold
など)に関するドキュメント。 - Sunflower を Jetpack Compose に移行する:
CoordinatorLayout
を含む Sunflower サンプルアプリのビューから Compose への移行プロセスを説明するブログ投稿。
あなたへのおすすめ
- 注: JavaScript がオフになっている場合はリンクテキストが表示されます
- マテリアル コンポーネントとレイアウト
- Compose でのウィンドウ インセット
- スクロール