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 */ } } }
一般的なユースケース
ツールバーを折りたたむ / 開く
View システムで CoordinatorLayout
を使用してツールバーを折りたたむ / 展開するには、AppBarLayout
をツールバーのコンテナとして使用します。次に、関連するスクロール可能なビュー(RecyclerView
や NestedScrollView
など)で XML で Behavior
から layout_behavior
を指定して、スクロールに応じてツールバーがどのように折りたたまれるかを宣言できます。
Compose では、TopAppBarScrollBehavior
を通じて同様の効果を実現できます。たとえば、上にスクロールしたときにツールバーが表示されるよう、折りたたみ/展開するツールバーを実装する手順は次のとおりです。
TopAppBarDefaults.enterAlwaysScrollBehavior()
を呼び出してTopAppBarScrollBehavior
を作成します。- 作成した
TopAppBarScrollBehavior
をTopAppBar
に渡します。 Scaffold
のModifier.nestedScroll
を介してNestedScrollConnection
を接続して、スクロール可能なコンテンツが上下にスクロールしたときに、Scaffold がネストされたスクロール イベントを受信できるようにします。これにより、コンテンツがスクロールしたときに、含まれるアプリバーを適切に折りたたんだり展開したりできます。// 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)) Divider() 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 サンプルアプリの View から Compose への移行プロセスを文書化したものです。
あなたへのおすすめ
- 注: JavaScript がオフになっている場合はリンクテキストが表示されます
- マテリアル コンポーネントとレイアウト
- Compose のウィンドウ インセット
- スクロール