CoordinatorLayout
是 ViewGroup
,可啟用複雜、重疊和巢狀的版面配置。它可做為容器,為其中包含的 View 啟用特定 Material Design 互動,例如展開/收合工具列和底部功能表。
在 Compose 中,CoordinatorLayout
最接近的等效項是 Scaffold
。Scaffold
提供內容版位,可將 Material Design 元件合併成常見的螢幕模式和互動。本頁面說明如何將 CoordinatorLayout
實作項目遷移至 Compose 中的 Scaffold
。
遷移步驟
如要將 CoordinatorLayout
遷移至 Scaffold
,請按照下列步驟操作:
在下列程式碼片段中,
CoordinatorLayout
包含AppBarLayout
,用於包含ToolBar
、ViewPager
和FloatingActionButton
。從 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" />
在 Fragment 或 Activity 中,取得對您剛新增的
ComposeView
的參照,並在其上呼叫setContent
方法。在方法的主體中,將Scaffold
設為內容:composeView.setContent { Scaffold(Modifier.fillMaxSize()) { contentPadding -> // Scaffold contents // ... } }
在
Scaffold
的內容中,新增螢幕的主要內容。由於上述 XML 中的主要內容是ViewPager2
,我們會使用HorizontalPager
,這是 Compose 的等效項目。Scaffold
的content
lambda 也會接收應套用至內容根層級的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 中,透過 layout_behavior
指定 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
也提供其他 TopAppBarScrollBehavior
,例如 exitUntilCollapsedScrollBehavior
,只會在捲動至內容底部時展開應用程式列。
如要建立完全自訂的效果 (例如視差效果),您也可以自行建立 NestedScrollConnection
,並在內容捲動時手動偏移工具列。如需程式碼範例,請參閱 AOSP 上的巢狀捲動範例。
導覽匣
您可以使用 DrawerLayout
做為根檢視區塊,藉此透過 View 實作導覽匣。而您的 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 // ... } }
詳情請參閱「Drawers」。
Snackbar
Scaffold
提供 snackbarHost
插槽,可接受 SnackbarHost
可組合項來顯示 Snackbar
。
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 // ... }
詳情請參閱「Snackbar」。
瞭解詳情
如要進一步瞭解如何將 CoordinatorLayout
遷移至 Compose,請參閱下列資源:
- Material Design 元件和版面配置:說明 Compose 支援的 Material Design 元件,例如
Scaffold
。 - 將 Sunflower 遷移至 Jetpack Compose:這篇網誌文章記錄了 Sunflower 範例應用程式從 View 遷移至 Compose 的過程,其中包含
CoordinatorLayout
。
為您推薦
- 注意:系統會在 JavaScript 關閉時顯示連結文字
- Material Design 元件和版面配置
- Compose 中的視窗插邊
- 捲動