一、Dialog
Dialog
组件的参数如下:
kotlin
@Composable
fun Dialog(
onDismissRequest: () -> Unit, //当用户试图取消对话框时执行
properties: DialogProperties = DialogProperties(), //用于进一步定义对话框的行为
content: @Composable () -> Unit //对话框的布局样式
) {...}
其中content
允许我们通过传入自己的Composable
组件来描述Dialog
页面。下面是一个简单的例子:
kotlin
@Composable
fun Greeting() {
var showDialog by remember { mutableStateOf(false) }
Column(
modifier = Modifier.fillMaxSize(),
horizontalAlignment = Alignment.CenterHorizontally,
verticalArrangement = Arrangement.Center
) {
Button( //用于显示Dialog
onClick = { showDialog = true }, //修改showDialog的值
modifier = Modifier.padding(16.dp)
) {
Icon(imageVector = Icons.Default.Delete, contentDescription = null)
Text(text = "Show Dialog")
}
//showDialog为true,展示Dialog
if (showDialog) {
Dialog(
onDismissRequest = { showDialog = false },
content = { //定义Dialog的样式
Column(
modifier = Modifier
.width(250.dp)
.height(200.dp)
.background(Color.White)
.padding(25.dp)
) {
Text(text = "删除文件")
Spacer(modifier = Modifier.height(10.dp))
Text(text = "您确定要删除这个文件吗?")
Spacer(modifier = Modifier.height(30.dp))
Row(
modifier = Modifier.fillMaxWidth(),
horizontalArrangement = Arrangement.SpaceBetween
) {
Button(
onClick = {
// 执行删除操作
showDialog = false
}
) {
Text(text = "确定")
}
Button(
onClick = {
// 取消删除操作
showDialog = false
}
) {
Text(text = "取消")
}
}
}
},
)
}
}
}
具体看看UI效果
properties
参数定制一些对话框特有的行为,看源码:
kotlin
@Immutable
class DialogProperties constructor(
val dismissOnBackPress: Boolean = true, //是否按返回键可以关闭对话框
val dismissOnClickOutside: Boolean = true, //触摸对话框外部是否可以关闭对话框
val securePolicy: SecureFlagPolicy = SecureFlagPolicy.Inherit,
val usePlatformDefaultWidth: Boolean = true, //对话框内容的宽度是否应该是限于平台默认值,小于屏幕宽度
val decorFitsSystemWindows: Boolean = true
) {...}
Compose
的对话框不像传统视图的对话框那样通过show()
、dismiss()
等命令式的方式显隐,它像不同的Composable
组件一样,显示与否要看是否在重组中被执行,所以它的显示与否要依赖状态控制。Dialog
和普通Composable
组件的不同在于其底层需要依赖独立的Window进行显示。
二、AlertDialog警告对话框
AlertDialog
是在Dialog
的基础上封装出来的,所以很多参数很相似,它的具体参数如下:
kotlin
@Composable
fun AlertDialog(
onDismissRequest: () -> Unit,
buttons: @Composable () -> Unit, //定义一些功能按钮
modifier: Modifier = Modifier,
title: (@Composable () -> Unit)? = null, //对话框的标题,不是必须的
text: @Composable (() -> Unit)? = null, //对话框的内容,不是必须的
shape: Shape = MaterialTheme.shapes.medium,
backgroundColor: Color = MaterialTheme.colors.surface,
contentColor: Color = contentColorFor(backgroundColor),
properties: DialogProperties = DialogProperties()
) {...}
除了上面这个还有另一个创建AlertDialog
的方法,并且这个方法是在上面方法的基础上封装出来的,源码如下:
kotlin
@Composable
fun AlertDialog(
onDismissRequest: () -> Unit,
confirmButton: @Composable () -> Unit, //定义了确定按钮
modifier: Modifier = Modifier,
dismissButton: @Composable (() -> Unit)? = null, //定义了取消按钮
title: @Composable (() -> Unit)? = null,
text: @Composable (() -> Unit)? = null,
shape: Shape = MaterialTheme.shapes.medium,
backgroundColor: Color = MaterialTheme.colors.surface,
contentColor: Color = contentColorFor(backgroundColor),
properties: DialogProperties = DialogProperties()
) {...}
下面通过使用AlertDialog
改造上一个例子中的代码以实现与上一个例子一样的效果,代码如下:
kotlin
@Composable
fun Greeting() {
var showDialog by remember { mutableStateOf(false) }
Column(
modifier = Modifier.fillMaxSize(),
horizontalAlignment = Alignment.CenterHorizontally,
verticalArrangement = Arrangement.Center
) {
Button( //用于显示Dialog
onClick = { showDialog = true }, //修改showDialog的值
modifier = Modifier.padding(16.dp)
) {
Icon(imageVector = Icons.Default.Delete, contentDescription = null)
Text(text = "Show Dialog")
}
//showDialog为true,展示Dialog
if (showDialog) {
AlertDialog(
onDismissRequest = { showDialog = false },
title = { Text(text = "删除文件") },
text = { Text(text = "您确定要删除这个文件吗?") },
buttons = {
Row(
modifier = Modifier
.fillMaxWidth()
.padding(bottom = 20.dp),
horizontalArrangement = Arrangement.Center
) {
Button(
onClick = {
// 执行删除操作
showDialog = false
}
) {
Text(text = "确定")
}
Spacer(modifier = Modifier.width(50.dp))
Button(
onClick = {
// 取消删除操作
showDialog = false
}
) {
Text(text = "取消")
}
}
}
)
}
}
}
UI效果
三、TopAppBar
类似于Toolbar
的功能,先看看它的参数:
kotlin
@Composable
fun TopAppBar(
modifier: Modifier = Modifier,
backgroundColor: Color = MaterialTheme.colors.primarySurface,
contentColor: Color = contentColorFor(backgroundColor),
elevation: Dp = AppBarDefaults.TopAppBarElevation, //应用栏的海拔高度
contentPadding: PaddingValues = AppBarDefaults.ContentPadding, //应用栏内容的内边距
content: @Composable RowScope.() -> Unit //具体布局实现
) {
AppBar(...)
}
可以看到TopAppBar
是在AppBar
的基础上封装出来的,除了上面这个方法还有另一个创建TopAppBar
的方法,如下:
kotlin
@Composable
fun TopAppBar(
title: @Composable () -> Unit,
modifier: Modifier = Modifier,
navigationIcon: @Composable (() -> Unit)? = null, //显示在TopAppBar上开始时的图标,通常应该是一个IconButton或IconToggleButton,例如返回键头
actions: @Composable RowScope.() -> Unit = {}, //显示在TopAppBar上结束的图标,默认有RowScope作用域横向排列
backgroundColor: Color = MaterialTheme.colors.primarySurface,
contentColor: Color = contentColorFor(backgroundColor),
elevation: Dp = AppBarDefaults.TopAppBarElevation
) {
AppBar(...)
}
下面看一个具体的使用的例子:
kotlin
@Composable
fun Greeting() {
Column {
TopAppBar(
elevation = 4.dp,
title = {
Text("TopAppBar")
},
backgroundColor = MaterialTheme.colors.primarySurface,
navigationIcon = { //返回箭头
IconButton(onClick = { }) {
Icon(Icons.Filled.ArrowBack, null)
}
}, actions = { //末尾添加分享和设置按钮
IconButton(onClick = { }) {
Icon(Icons.Filled.Share, null)
}
IconButton(onClick = { }) {
Icon(Icons.Filled.Settings, null)
}
})
Text("Hello World")
}
}
UI效果
四、Snackbar
Snackbar
的参数如下:
kotlin
@Composable
fun Snackbar(
modifier: Modifier = Modifier,
action: @Composable (() -> Unit)? = null, //将动作比如以按钮的形式添加到Snackbar上
actionOnNewLine: Boolean = false, //是否将动作以新的一行显示
shape: Shape = MaterialTheme.shapes.small,
backgroundColor: Color = SnackbarDefaults.backgroundColor,
contentColor: Color = MaterialTheme.colors.surface,
elevation: Dp = 6.dp,
content: @Composable () -> Unit
) {...}
Snackbar
的应用场景有哪些(GPT的回答)?
Jetpack Compose
中的Snackbar
组件主要用于在屏幕底部显示短暂的提示或消息。它的常见应用场景包括:
- 操作反馈:在用户执行操作后,给出简短的反馈提示,比如"保存成功"。
- 警告信息:当某些操作无法执行或出现错误时,向用户展示警告或错误信息。
- 确认操作:在可能产生破坏性后果的操作前,使用Snackbar提示用户进行确认。
- 通知信息:向用户展示一些没有及时需要交互的通知信息。
- 撤销操作:提供一个按钮允许用户撤销最近执行的操作。
- 临时交互:
Snackbar
可以包含按钮等简单交互,用于临时操作。
相比Dialog
,Snackbar
出现在屏幕底部,对主要内容影响较小,适合用于展示轻量级的提示信息。
需要注意的是,Snackbar
不应该过度使用,或者用于展示太多重要的内容,这会影响交互流程与用户体验。合理使用Snackbar
可以在不打断用户的情况下提供有效的反馈。
下面是一个简单的例子:
kotlin
@Composable
fun Greeting() {
Column(modifier = Modifier.fillMaxSize()) {
val (snackbarVisibleState, setSnackBarState) = remember { mutableStateOf(false) }
Box(modifier = Modifier.weight(1F)) {
Button( //用于显示和隐藏Snackbar
onClick = { setSnackBarState(!snackbarVisibleState) }) {
if (snackbarVisibleState) {
Text("隐藏Snackbar")
} else {
Text("显示Snackbar")
}
}
}
//Snackbar
if (snackbarVisibleState) {
Snackbar(
action = {
Button(onClick = {}) {
Text("升级App")
}
},
modifier = Modifier.padding(8.dp)
) { Text(text = "检测到有新版本") }
}
}
}
UI效果
五、Card
跟CardView
的效果类似,下面是它的参数
kotlin
@Composable
@NonRestartableComposable
fun Card(
modifier: Modifier = Modifier,
shape: Shape = MaterialTheme.shapes.medium, //圆角大小
backgroundColor: Color = MaterialTheme.colors.surface,
contentColor: Color = contentColorFor(backgroundColor),
border: BorderStroke? = null, //外边框
elevation: Dp = 1.dp, //阴影大小
content: @Composable () -> Unit
) {...}
一个简单的例子
kotlin
@Composable
fun Greeting() {
Card(
modifier = Modifier
.fillMaxWidth()
.padding(15.dp)
.clickable {
showToast("Card被点击了")
},
elevation = 10.dp
) {
Column(
modifier = Modifier.padding(15.dp)
) {
Text(text = "welcome to Jetpack Compose Playground")
}
}
}
UI效果
Card
最常见的需求应该是调整阴影和圆角大小,下面是一个通过Slider
控件动态调整Card
阴影和圆角大小的例子:
kotlin
@Composable
fun Greeting() {
var cardElevation by remember { mutableStateOf(8.dp) }
var cardCornerSize by remember { mutableStateOf(16.dp) }
Column(
modifier = Modifier
.fillMaxSize()
.padding(16.dp),
verticalArrangement = Arrangement.spacedBy(16.dp)
) {
// 可调整圆角和阴影大小的Card
Card(
modifier = Modifier
.fillMaxWidth()
.height(100.dp)
.padding(16.dp)
.background(Color.White),
elevation = cardElevation, // 阴影大小
shape = RoundedCornerShape(cardCornerSize) //圆角大小
) {
Box(
modifier = Modifier.fillMaxSize(),
contentAlignment = Alignment.Center
) {
Text(text = "Customized Card")
}
}
Text(text = "调整阴影大小")
//用Slider调整阴影大小
Slider(
value = cardElevation.value,
onValueChange = { newValue ->
cardElevation = newValue.dp
},
valueRange = 0f..16f, //调整阴影大小的范围
steps = 17,
modifier = Modifier.fillMaxWidth()
)
Text(text = "调整圆角大小")
//用Slider调整圆角大小
Slider(
value = cardCornerSize.value,
onValueChange = { newValue ->
cardCornerSize = newValue.dp
},
valueRange = 0f..32f, //调整圆角大小的范围
steps = 33,
modifier = Modifier.fillMaxWidth()
)
}
}
UI效果
六、Divider
画细实线。参数如下:
kotlin
fun Divider(
modifier: Modifier = Modifier,
color: Color = MaterialTheme.colors.onSurface.copy(alpha = DividerAlpha),
thickness: Dp = 1.dp, //线的厚度
startIndent: Dp = 0.dp //起始偏移量
) {
UI效果
那在Compose
中如何绘制虚线呢?下面是一个例子:
kotlin
@Composable
fun Greeting() {
Canvas(
modifier = Modifier
.padding(0.dp, 10.dp, 0.dp, 10.dp)
.fillMaxWidth()
) {
drawLine(
start = Offset(0f, size.height / 2),
end = Offset(size.width, size.height / 2),
color = Color.Black,
strokeWidth = 5f, //线的高度,5像素
pathEffect = dashPathEffect(
floatArrayOf(10.dp.toPx(), 2.dp.toPx()), //虚线的绘制长度和间隔
5.dp.toPx() //第一段和最后一段的偏移量,如果给0就正常按10-2-10-2...绘制
)
)
}
}
UI效果
七、BadgedBox
BadgedBox
的参数如下:
kotlin
@Composable
fun BadgedBox(
badge: @Composable BoxScope.() -> Unit,
modifier: Modifier = Modifier,
content: @Composable BoxScope.() -> Unit,
) {...}
BadgedBox
是 Jetpack Compose
中的一个组件,用于在屏幕上显示一个带有文本或图标的小窗口。它可以用于在应用程序中显示通知、提醒、错误信息、进度条、广告等信息。下面是一个简单的例子:
kotlin
@Composable
fun Greeting() {
//BottomNavigation
BottomNavigation {
//BottomNavigationItem
BottomNavigationItem(
icon = {
//BadgedBox
BadgedBox(badge = { Badge { Text("8") } }) {
Icon(
Icons.Filled.Favorite,
contentDescription = null
)
}
},
selected = false,
onClick = {})
}
}
UI效果
进一步完善一个点赞的例子,点击"加"点赞数增加,点击"减"点赞数减少,并伴随着UI的变化:
kotlin
@Composable
fun Greeting() {
var likeNum by remember { mutableStateOf(0) }
val color = if (likeNum > 0) Color.Red else Color.Gray
Column(modifier = Modifier.fillMaxSize()) {
Spacer(modifier = Modifier.height(10.dp))
//BadgedBox
BadgedBox(badge = {
if (likeNum > 0) {
Badge {
Text("$likeNum")
}
}
}) {
Icon(
Icons.Filled.Favorite,
contentDescription = null,
tint = color
)
}
//按钮加
Spacer(modifier = Modifier.height(20.dp))
Button(onClick = { likeNum++ }) {
Text(text = "加")
}
//按钮减
Spacer(modifier = Modifier.height(20.dp))
Button(onClick = { if (likeNum > 0) likeNum-- }) {
Text(text = "减")
}
}
}
UI效果
八、DropdownMenu
DropdownMenu
可以创建一个下拉菜单。先看看它的参数:
kotlin
@Composable
fun DropdownMenu(
expanded: Boolean, //是否展开
onDismissRequest: () -> Unit, //定义消失时的行为
modifier: Modifier = Modifier,
offset: DpOffset = DpOffset(0.dp, 0.dp),
properties: PopupProperties = PopupProperties(focusable = true), //各种焦点或触摸行为
content: @Composable ColumnScope.() -> Unit //具体布局实现
) {...}
下面是一个简单的例子:
kotlin
@Composable
fun Greeting() {
var expanded by remember { mutableStateOf(false) }
var selectedGender by remember { mutableStateOf("请选择性别") }
val items = listOf("男", "女")
Box(
modifier = Modifier
.fillMaxSize()
.wrapContentSize(Alignment.TopStart)
) {
OutlinedButton(onClick = { expanded = true }) { //点击按钮展开DropdownMenu
Text(text = selectedGender)
Icon(imageVector = Icons.Filled.ArrowDropDown, contentDescription = null)
}
DropdownMenu(
expanded = expanded,
onDismissRequest = { expanded = false },
) {
items.forEachIndexed { index, itemStr ->
DropdownMenuItem(onClick = {
selectedGender = items[index]
expanded = false
}) {
Text(text = itemStr)
}
}
}
}
}
UI效果
九、ModalBottomSheetLayout
先看一下参数:
kotlin
@Composable
@ExperimentalMaterialApi
fun ModalBottomSheetLayout(
sheetContent: @Composable ColumnScope.() -> Unit,
modifier: Modifier = Modifier,
sheetState: ModalBottomSheetState =
rememberModalBottomSheetState(Hidden),
sheetShape: Shape = MaterialTheme.shapes.large,
sheetElevation: Dp = ModalBottomSheetDefaults.Elevation,
sheetBackgroundColor: Color = MaterialTheme.colors.surface,
sheetContentColor: Color = contentColorFor(sheetBackgroundColor),
scrimColor: Color = ModalBottomSheetDefaults.scrimColor,
content: @Composable () -> Unit
) {...}
这是一个实验性质的API,参数同样是一些圆角、高度、颜色等,具体看一些例子可能清楚一些,下面是一个例子。
kotlin
@OptIn(ExperimentalMaterialApi::class)
@Composable
fun Greeting() {
val fullHeight = LocalConfiguration.current.screenHeightDp.dp
val state = rememberModalBottomSheetState(ModalBottomSheetValue.Hidden)
val scope = rememberCoroutineScope()
ModalBottomSheetLayout(
sheetState = state,
sheetContent = {
//自己随意定制
LazyColumn(modifier = Modifier.height(fullHeight / 2)) {
items(50) {
ListItem(
text = { Text("Item $it") },
icon = {
Icon(
Icons.Default.Favorite,
contentDescription = null
)
}
)
}
}
}
) {
//点击按钮显示Sheet
Button(onClick = { scope.launch { state.show() } }) {
Text("Click to show sheet")
}
}
}
UI效果
但是快速下拉会把整个ModalBottomSheetLayout
拉下来,所以可能还需要做手势拦截,这里就不展开了。另外点击外部区域也会消失,这个暂时也没找到解决办法。如果有需求刚好是底部弹出,且下拉和点击外部消失,那用它还是可以的,下面是一个相对实用的例子:
kotlin
@OptIn(ExperimentalMaterialApi::class)
@Composable
fun Greeting() {
val state = rememberModalBottomSheetState(ModalBottomSheetValue.Hidden)
val scope = rememberCoroutineScope()
ModalBottomSheetLayout(
sheetState = state,
sheetContent = {
Column(
modifier = Modifier.fillMaxWidth(),
horizontalAlignment = Alignment.CenterHorizontally
) {
Spacer(modifier = Modifier.height(10.dp))
Text("确认要删除文件吗?")
Spacer(modifier = Modifier.height(16.dp))
TextButton(onClick = { /* Handle confirmation */ }) {
Text("确认")
}
Divider()
TextButton(onClick = { /* Handle cancel */ }) {
Text("取消")
}
}
}
) {
//点击按钮显示Sheet
Button(onClick = {
scope.launch {
state.show()
}
}) {
Text("Click to show sheet")
}
}
}
UI效果(点击外部消失和下拉消失)
如果对于底部弹窗有很强的定制需求,可以自己封装或借助第三方库,例如bottomsheetdialog-compose。
十、ModalDrawer
参数
kotlin
@Composable
@OptIn(ExperimentalMaterialApi::class)
fun ModalDrawer(
drawerContent: @Composable ColumnScope.() -> Unit,
modifier: Modifier = Modifier,
drawerState: DrawerState = rememberDrawerState(DrawerValue.Closed),
gesturesEnabled: Boolean = true,
drawerShape: Shape = MaterialTheme.shapes.large,
drawerElevation: Dp = DrawerDefaults.Elevation,
drawerBackgroundColor: Color = MaterialTheme.colors.surface,
drawerContentColor: Color = contentColorFor(drawerBackgroundColor),
scrimColor: Color = DrawerDefaults.scrimColor,
content: @Composable () -> Unit
) {...}
ModalDrawer
是一个专门用于创建模态抽屉的组件,它可以在页面上打开一个模态抽屉,并且可以在抽屉中显示一些内容。ModalDrawer
通常用于实现类似于Android
中的Navigation Drawer
的效果。下面看一个例子:
kotlin
@Composable
fun Greeting() {
val drawerState = rememberDrawerState(DrawerValue.Closed)
val imageVector = if (drawerState.isOpen) Icons.Filled.ArrowBack else Icons.Filled.List
val scope = rememberCoroutineScope()
Column {
//在TopAppBar下面创建ModalDrawer
TopAppBar(elevation = 4.dp,
title = {
Text("TopAppBar")
},
backgroundColor = MaterialTheme.colors.primarySurface,
navigationIcon = { //返回箭头
IconButton(onClick = {
scope.launch {
if (drawerState.isOpen) { //修改图标,点击图标可以开启或关闭ModalDrawer
drawerState.close()
} else {
drawerState.open()
}
}
}) {
Icon(imageVector, null)
}
})
//ModalDrawer
ModalDrawer(drawerState = drawerState, drawerContent = {
Box(modifier = Modifier.fillMaxSize(), contentAlignment = Alignment.Center) {
Button(onClick = {
scope.launch {
drawerState.close()
}
}) {
Text("关闭ModalDrawer")
}
}
}, content = {
Box(modifier = Modifier.fillMaxSize(), contentAlignment = Alignment.Center) {
Text(text = "Activity主要显示内容的区域", textAlign = TextAlign.Center)
}
})
}
}
UI效果
十一、Scaffold
Scaffold
就是在ModalDrawer
的基础上封装出来的脚手架,它有更快捷的定义UI的方式,看它的参数:
kotlin
@Composable
fun Scaffold(
modifier: Modifier = Modifier,
scaffoldState: ScaffoldState = rememberScaffoldState(),
topBar: @Composable () -> Unit = {}, //topBar
bottomBar: @Composable () -> Unit = {}, //bottomBar
snackbarHost: @Composable (SnackbarHostState) -> Unit = { SnackbarHost(it) },
floatingActionButton: @Composable () -> Unit = {}, //FAB
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
) {
val child = @Composable { childModifier: Modifier ->
Surface(modifier = childModifier, color = backgroundColor, contentColor = contentColor) {
ScaffoldLayout(...)
}
}
if (drawerContent != null) {
ModalDrawer(...)
} else {
child(modifier)
}
}
聚合了很多控件的脚手架,改造上一个ModalDrawer
例子中的代码,将TopAppBar
的代码塞到topBar
参数中:
kotlin
@SuppressLint("UnusedMaterialScaffoldPaddingParameter")
@Composable
fun Greeting1() {
val drawerState = rememberScaffoldState(rememberDrawerState(DrawerValue.Closed))
val scope = rememberCoroutineScope()
Scaffold(topBar = { //TopAppBar的代码塞到topbar参数中
TopAppBar(elevation = 4.dp,
title = {
Text("TopAppBar")
},
backgroundColor = MaterialTheme.colors.primarySurface,
navigationIcon = { //返回箭头
IconButton(onClick = {
scope.launch {
drawerState.drawerState.open()
}
}) {
Icon(Icons.Filled.List, null)
}
})
}, scaffoldState = drawerState, drawerContent = {
Box(modifier = Modifier.fillMaxSize(), contentAlignment = Alignment.Center) {
Button(onClick = {
scope.launch {
drawerState.drawerState.close()
}
}) {
Text("关闭Drawer")
}
}
}, content = {
Box(modifier = Modifier.fillMaxSize(), contentAlignment = Alignment.Center) {
Text(text = "Activity主要显示内容的区域", textAlign = TextAlign.Center)
}
})
}
UI效果
可以看到跟上一个例子的区别是Drawer
出现的时候TopAppBar
被遮挡了。
十二、BottomSheetScaffold
又是一个封装的脚手架,参数如下:
kotlin
@Composable
@ExperimentalMaterialApi
fun BottomSheetScaffold(
sheetContent: @Composable ColumnScope.() -> Unit,
modifier: Modifier = Modifier,
scaffoldState: BottomSheetScaffoldState = rememberBottomSheetScaffoldState(),
topBar: (@Composable () -> Unit)? = null,
snackbarHost: @Composable (SnackbarHostState) -> Unit = { SnackbarHost(it) },
floatingActionButton: (@Composable () -> Unit)? = null,
floatingActionButtonPosition: FabPosition = FabPosition.End,
sheetGesturesEnabled: Boolean = true,
sheetShape: Shape = MaterialTheme.shapes.large,
sheetElevation: Dp = BottomSheetScaffoldDefaults.SheetElevation,
sheetBackgroundColor: Color = MaterialTheme.colors.surface,
sheetContentColor: Color = contentColorFor(sheetBackgroundColor),
sheetPeekHeight: Dp = BottomSheetScaffoldDefaults.SheetPeekHeight, //sheet收缩时的高度
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
) {...}
下面是一个例子,默认展示3条,用户想要操作更多向上划出:
kotlin
enum class Page(val title: String, val icon: Int) {
HOME("home", R.drawable.ic_home),
SEARCH("search", R.drawable.ic_search),
PROFILE("profile", R.drawable.ic_profile),
SETTING("setting", R.drawable.ic_setting),
MESSAGE("message", R.drawable.ic_message),
PHONE("phone", R.drawable.ic_phone),
SHARE("share", R.drawable.ic_share)
}
@OptIn(ExperimentalMaterialApi::class)
@Composable
fun Greeting() {
val scope = rememberCoroutineScope()
val scaffoldState = rememberBottomSheetScaffoldState()
val page = Page.values()
BottomSheetScaffold(
scaffoldState = scaffoldState,
sheetPeekHeight = 110.dp,
drawerBackgroundColor = Color.LightGray,
sheetContent = {
LazyVerticalGrid(
columns = GridCells.Fixed(3),
// content padding
contentPadding = PaddingValues(
start = 12.dp,
top = 0.dp,
end = 12.dp,
bottom = 0.dp
),
content = {
items(page.size) { index ->
Card(
modifier = Modifier
.padding(6.dp, 10.dp)
.fillMaxWidth()
.clickable {
//scope.launch { scaffoldState.bottomSheetState.collapse() }
},
elevation = 6.dp
) {
Column(
modifier = Modifier
.fillMaxWidth()
.padding(10.dp)
) {
Icon(
bitmap = ImageBitmap.imageResource(page[index].icon),
contentDescription = page[index].title
)
Text(text = page[index].title)
}
}
}
}
)
}, content = { _ ->
Box(Modifier.fillMaxSize(), contentAlignment = Alignment.Center) {
Text("Activity主要显示内容的区域")
}
})
}
UI效果
十三、BottomNavigation
BottomNavigation
底部导航,参数如下:
kotlin
@Composable
fun BottomNavigation(
modifier: Modifier = Modifier,
backgroundColor: Color = MaterialTheme.colors.primarySurface,
contentColor: Color = contentColorFor(backgroundColor),
elevation: Dp = BottomNavigationDefaults.Elevation,
content: @Composable RowScope.() -> Unit //包N个BottomNavigationItem
) {...}
下面是一个简单的例子
kotlin
@Composable
fun Greeting() {
var text by remember { mutableStateOf("Home") }
Column(
modifier = Modifier
.fillMaxSize()
) {
Box(
modifier = Modifier
.weight(1F)
.fillMaxWidth(),
contentAlignment = Alignment.Center
) {
Text(text = text)
}
BottomNavigation {
BottomNavigationItem(
selected = true,
onClick = { text = "Home" },
icon = { Icon(bitmap = ImageBitmap.imageResource(id = R.drawable.ic_home), contentDescription = "Home") },
label = { Text(text = "Home") }
)
BottomNavigationItem(
selected = false,
onClick = { text = "Search" },
icon = { Icon(bitmap = ImageBitmap.imageResource(id = R.drawable.ic_search), contentDescription = "Search") },
label = { Text(text = "Search") }
)
BottomNavigationItem(
selected = false,
onClick = { text = "Profile" },
icon = { Icon(bitmap =ImageBitmap.imageResource(id = R.drawable.ic_profile), contentDescription = "Profile") },
label = { Text(text = "Profile") }
)
}
}
}
UI效果
十四、NavigationRail
侧面导航NavigationRail
,参数如下:
kotlin
@Composable
fun NavigationRail(
modifier: Modifier = Modifier,
backgroundColor: Color = MaterialTheme.colors.surface,
contentColor: Color = contentColorFor(backgroundColor),
elevation: Dp = NavigationRailDefaults.Elevation,
header: @Composable (ColumnScope.() -> Unit)? = null,
content: @Composable ColumnScope.() -> Unit
) {...}
下面是一个例子:
kotlin
enum class Page(val title: String) {
HOME("home"),
SEARCH("Search"),
PROFILE("profile")
}
@Composable
fun Greeting() {
var selectedItem by remember { mutableStateOf(0) }
val pages = Page.values()
Row {
//创建NavigationRail
NavigationRail {
pages.forEachIndexed { index, item ->
when (item) {
Page.HOME -> {
////创建NavigationRail
NavigationRailItem(
label = { Text(item.title) },
icon = {
Icon(
bitmap = ImageBitmap.imageResource(id = R.drawable.ic_home),
contentDescription = null
)
},
selected = selectedItem == index,
onClick = { selectedItem = index })
}
Page.SEARCH -> {
NavigationRailItem(label = { Text(item.title) },
icon = {
Icon(
bitmap = ImageBitmap.imageResource(id = R.drawable.ic_search),
contentDescription = null
)
},
selected = selectedItem == index,
onClick = { selectedItem = index })
}
Page.PROFILE -> {
NavigationRailItem(label = { Text(item.title) },
icon = {
Icon(
bitmap = ImageBitmap.imageResource(id = R.drawable.ic_profile),
contentDescription = null
)
},
selected = selectedItem == index,
onClick = { selectedItem = index }
)
}
}
}
}
Box(modifier = Modifier.fillMaxSize(), contentAlignment = Alignment.Center) {
Text(pages[selectedItem].title)
}
}
}
UI效果
十五、Surface
Surface
是一个抽象的类,它表示一个可以绘制图形的区域,它的参数如下:
kotlin
@Composable
fun Surface(
modifier: Modifier = Modifier,
shape: Shape = RectangleShape,
color: Color = MaterialTheme.colors.surface,
contentColor: Color = contentColorFor(color),
border: BorderStroke? = null,
elevation: Dp = 0.dp,
content: @Composable () -> Unit
) {...}
常用的用法有:
1、提供背景、圆角、边框和阴影
kotlin
@Composable
fun Greeting() {
Box(modifier = Modifier.fillMaxSize(), contentAlignment = Alignment.Center) {
Surface(
color = Color.LightGray, elevation = 8.dp, shape = RoundedCornerShape(8.dp)
) {
Text(
text = "Surface中的文本", modifier = Modifier.padding(16.dp)
)
}
}
}
UI效果
顺着这个思路可以封装各种边框圆角等卡片样式的布局。
2、绘制以生成自定义图形
kotlin
@Composable
fun Greeting() {
Box(modifier = Modifier.fillMaxSize(), contentAlignment = Alignment.Center) {
Surface(
color = Color.White,
shape = RectangleShape,
elevation = 4.dp
) {
//绘制矩形
Canvas(modifier = Modifier.size(300.dp)) {
drawRect(
color = Color.LightGray,
style = Fill,
topLeft = Offset(75.dp.toPx(), 75.dp.toPx()),
size = Size(150.dp.toPx(), 150.dp.toPx())
)
}
}
}
}
UI效果
参考了以下内容
其他内容