CoordinatorLayout
是一个 ViewGroup
,它支持复杂、重叠和嵌套的布局。 它用作容器,以支持对其中包含的视图进行特定的 Material Design 交互,例如展开/折叠工具栏和底部工作表。
在 Compose 中,CoordinatorLayout
最接近的等效项是 Scaffold
。 Scaffold
提供内容插槽,用于将 Material 组件组合成常见的屏幕模式和交互。 此页面介绍了如何迁移您的 CoordinatorLayout
实现以在 Compose 中使用 Scaffold
。
迁移步骤
要将 CoordinatorLayout
迁移到 Scaffold
,请按照以下步骤操作
在下面的代码片段中,
CoordinatorLayout
包含一个用于包含ToolBar
的AppBarLayout
、一个ViewPager
和一个FloatingActionButton
。 将CoordinatorLayout
及其子元素从您的 UI 层次结构中注释掉,并添加一个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 中的ViewPager2
。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 */ } } }
常见用例
折叠和展开工具栏
在视图系统中,要使用 CoordinatorLayout
折叠和展开工具栏,您将使用 AppBarLayout
作为工具栏的容器。 然后,您可以通过 layout_behavior
在 XML 中指定关联的可滚动视图(如 RecyclerView
或 NestedScrollView
)上的 Behavior
,以声明工具栏在您滚动时如何折叠/展开。
在 Compose 中,您可以通过 TopAppBarScrollBehavior
实现类似的效果。 例如,要实现一个折叠/展开的工具栏,以便工具栏在您向上滚动时出现,请按照以下步骤操作
- 调用
TopAppBarDefaults.enterAlwaysScrollBehavior()
以创建TopAppBarScrollBehavior
。 - 将创建的
TopAppBarScrollBehavior
提供给TopAppBar
。 通过
Modifier.nestedScroll
在Scaffold
上连接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
作为根视图。 反过来,您的 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 // ... } }
请参阅 抽屉 以了解更多信息。
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 组件和布局:Compose 中支持的 Material Design 组件的文档,如
Scaffold
。 - 将 Sunflower 迁移到 Jetpack Compose:一篇博客文章,记录了 Sunflower 示例应用程序从视图到 Compose 的迁移之旅,其中包含一个
CoordinatorLayout
。
推荐给您
- 注意:当 JavaScript 关闭时,将显示链接文本
- Material 组件和布局
- Compose 中的窗口内边距
- 滚动