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 でのウィンドウ インセット
- スクロール