Compose 提供了大量基于 Material Design 的可组合项以及依赖项,旨在简化界面的构建。诸如 Drawer
、FloatingActionButton
和 TopAppBar
之类的元素都有提供。Material 组件大量使用槽位 API,这是 Compose 引入的一种模式,可在组合项之上带来一层自定义设置。可组合项通常采用 lambda (content: @Composable () -> Unit
)。
Scaffold
可以实现具有基本 Material Design 布局结构的界面。Scaffold
可以为最常见的顶级 Material 组件(如 TopAppBar
、BottomAppBar
、FloatingActionButton
和 Drawer
)提供槽位。通过使用 Scaffold
,可轻松确保这些组件得到适当放置且正确地协同工作。
@Composable
fun Scaffold(
modifier: Modifier = Modifier,
scaffoldState: ScaffoldState = rememberScaffoldState(),
topBar: @Composable () -> Unit = {},
bottomBar: @Composable () -> Unit = {},
snackbarHost: @Composable (SnackbarHostState) -> Unit = { SnackbarHost(it) },
floatingActionButton: @Composable () -> Unit = {},
floatingActionButtonPosition: FabPosition = FabPosition.End,
isFloatingActionButtonDocked: Boolean = false,
drawerContent: @Composable (ColumnScope.() -> Unit)? = null,
drawerGesturesEnabled: Boolean = true,
drawerShape: Shape = MaterialTheme.shapes.large,
drawerElevation: Dp = DrawerDefaults.Elevation,
drawerBackgroundColor: Color = MaterialTheme.colors.surface,
drawerContentColor: Color = contentColorFor(drawerBackgroundColor),
drawerScrimColor: Color = DrawerDefaults.scrimColor,
backgroundColor: Color = MaterialTheme.colors.background,
contentColor: Color = contentColorFor(backgroundColor),
content: @Composable (PaddingValues) -> Unit
): Unit
接下来实现一个 Scaffold 基础用法。
创建 TopBar
@Composable
fun TopBar(onMenuClicked: () -> Unit) {
TopAppBar(
title = {
Text(text = "Scaffold Example", color = Color.White)
},
navigationIcon = {
Icon(
imageVector = Icons.Default.Menu,
contentDescription = "Menu",
modifier = Modifier.clickable(onClick = onMenuClicked),
tint = Color.White
)
},
backgroundColor = Purple700,
elevation = 12.dp
)
}
创建 BottomBar
@Composable
fun BottomBar() {
BottomAppBar(
backgroundColor = Purple700
) {
Text(text = "BottomAppBar", color = Color.White)
}
}
创建 Content
@Composable
fun Content() {
Column(
verticalArrangement = Arrangement.Center,
horizontalAlignment = Alignment.CenterHorizontally,
modifier = Modifier
.fillMaxSize()
.background(Color.White)
) {
Text(text = "Content", color = Purple700)
}
}
创建 Drawer
@Composable
fun Drawer() {
Column(
Modifier
.background(Color.White)
.fillMaxSize()
) {
repeat(5) { item ->
Text(text = "Item $item", modifier = Modifier.padding(8.dp), color = Color.Black)
}
}
}
实现 FloatingActionButton 点击弹出 SnackBar
FloatingActionButton(
onClick = {
coroutineScope.launch {
when (scaffoldState.snackbarHostState.showSnackbar(
message = "Snack Bar",
actionLabel = "Dismiss"
)) {
SnackbarResult.Dismissed -> {
}
SnackbarResult.ActionPerformed -> {
}
}
}
}
) {
Text(text = "+", color = Color.White, fontSize = 26.sp)
}
所有需要的组件都创建完成,来组合 Scaffold。
@Composable
fun ScaffoldExample() {
val scaffoldState = rememberScaffoldState(rememberDrawerState(DrawerValue.Closed))
val coroutineScope = rememberCoroutineScope()
Scaffold(
scaffoldState = scaffoldState,
topBar = {
TopBar(
onMenuClicked = {
coroutineScope.launch {
scaffoldState.drawerState.open()
}
})
},
bottomBar = { BottomBar() },
drawerContent = {
Drawer()
},
content = {
Content()
},
floatingActionButton = {
FloatingActionButton(
onClick = {
coroutineScope.launch {
when (scaffoldState.snackbarHostState.showSnackbar(
message = "Snack Bar",
actionLabel = "Dismiss"
)) {
SnackbarResult.Dismissed -> {
}
SnackbarResult.ActionPerformed -> {
}
}
}
}
) {
Text(text = "+", color = Color.White, fontSize = 26.sp)
}
}
)
}
然后就可以在 Activity 中从 setContent 里调用 Scaffold 组合了。
class MainActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {
Surface(color = Color.White) {
ScaffoldExample()
}
}
}
}