CoordinatorLayout 是 ViewGroup,可啟用複雜、重疊和巢狀版面配置。這個容器可啟用特定 Material Design 互動,例如展開/收合工具列和底部功能表,適用於其中包含的 View。
在 Compose 中,CoordinatorLayout 最接近的對應項目是 Scaffold。Scaffold 提供內容位置,可將 Material Design 元件合併成常見的螢幕模式和互動。本頁說明如何遷移 CoordinatorLayout 實作項目,改用 Compose 中的 Scaffold。
遷移步驟
如要將 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" />在 Fragment 或 Activity 中,取得您剛才新增的
ComposeView參照,並呼叫其中的setContent方法。在方法主體中,將Scaffold設為其內容:composeView.setContent { Scaffold(Modifier.fillMaxSize()) { contentPadding -> // Scaffold contents // ... } }
在
Scaffold的內容中,加入畫面中的主要內容。由於上方 XML 中的主要內容是ViewPager2,因此我們會使用HorizontalPager,這是對應的 Compose 項目。Scaffold的contentlambda 函式也會收到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 上的巢狀捲動範例。
導覽匣
使用 Views 時,您可以使用 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 // ... } }
詳情請參閱「抽屜」。
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 範例應用程式從 Views 遷移至 Compose 的過程,其中包含
CoordinatorLayout。
為您推薦
- 注意:系統會在 JavaScript 關閉時顯示連結文字
- Material Design 元件和版面配置
- Compose 的視窗插邊
- 捲動