You can customize the 100 to match the UI from the picture, and here is an example:
首先,在BottomSheet
可组合函数中添加以下参数:
isBottomSheetVisible: Boolean
-用于控制底板的可见性.sheetState: SheetState
-底板的状态.onDismiss: () -> Unit
-取消底页的回调.然后,将ModalBottomSheet
Inside if (isBottomSheetVisible) {}
块包起来,并更改以下图纸属性:
onDismissRequest
到onDismiss
.sheetState
到sheetState
.containerColor
到Color.Transparent
.contentColor
到您的内容 colored颜色 ,例如文本 colored颜色 .shape
到RectangleShape
.dragHandle
%至null
%scrimColor
到设计的细布 colored颜色 (例如Color.Black.copy(alpha = .5f)
).windowInsets
设置为WindowInsets(0, 0, 0, 0)
,以展开系统栏下方的底部工作表.到目前为止,BottomSheet
个可组合元素应该如下所示:
@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun BottomSheet(
isBottomSheetVisible: Boolean,
sheetState: SheetState,
onDismiss: () -> Unit
) {
if (isBottomSheetVisible) {
ModalBottomSheet(
onDismissRequest = onDismiss,
sheetState = sheetState,
containerColor = Color.Transparent,
contentColor = MaterialTheme.colorScheme.onSurface,
shape = RectangleShape,
dragHandle = null,
scrimColor = Color.Black.copy(alpha = .5f),
windowInsets = WindowInsets(0, 0, 0, 0)
) {
// Implement the custom layout here ...
}
}
}
现在,您可以开始在ModalBottomSheet
的content
块内实现自定义布局:
ModalBottomSheet
的居中按钮可以包裹在Box
中,并对其进行进一步的定制:Box(
modifier = Modifier
.statusBarsPadding()
.fillMaxWidth()
.padding(8.dp),
contentAlignment = Alignment.Center
) {
FilledIconButton(
modifier = Modifier.size(48.dp),
onClick = onDismiss,
colors = IconButtonDefaults.filledIconButtonColors(
containerColor = MaterialTheme.colorScheme.background
)
) {
Icon(
imageVector = Icons.Rounded.Close,
contentDescription = "Dismiss the dialog."
)
}
}
Box
下面添加一个Column
,并实现其余的UI组件:Column(
modifier = Modifier
.navigationBarsPadding()
.padding(12.dp) // Outer padding
.clip(shape = RoundedCornerShape(24.dp))
.background(color = MaterialTheme.colorScheme.background)
.fillMaxWidth()
.padding(24.dp) // Inner padding
) {
Spacer(modifier = Modifier.height(16.dp))
OutlinedTextField(
modifier = Modifier.fillMaxWidth(),
value = "10th avenue, Some, State",
onValueChange = {},
label = { Text(text = "Delivery Address") },
readOnly = true,
shape = RoundedCornerShape(12.dp)
)
Spacer(modifier = Modifier.height(24.dp))
OutlinedTextField(
modifier = Modifier.fillMaxWidth(),
value = "09090606000",
onValueChange = {},
label = { Text(text = "Number we can call") },
readOnly = true,
shape = RoundedCornerShape(12.dp)
)
Spacer(modifier = Modifier.height(48.dp))
Row(
modifier = Modifier.fillMaxWidth(),
verticalAlignment = Alignment.CenterVertically,
horizontalArrangement = Arrangement.SpaceBetween
) {
OutlinedButton(
onClick = {},
content = { Text(text = "Pay on delivery") }
)
OutlinedButton(
onClick = {},
content = { Text(text = "Pay with card") }
)
}
}
最后,在需要底页的任何地方,声明以下变量:
scope
-用于有效地展开或隐藏底片的协程作用域.isBottomSheetVisible
-用于控制底板可见性.sheetState
-底部工作表的状态.然后,实施BottomSheet
个可组合:
val scope = rememberCoroutineScope()
var isBottomSheetVisible by rememberSaveable { mutableStateOf(false) }
val sheetState = rememberModalBottomSheetState(
skipPartiallyExpanded = true
)
BottomSheet(
isBottomSheetVisible = isBottomSheetVisible,
sheetState = sheetState,
onDismiss = {
scope.launch { sheetState.hide() }
.invokeOnCompletion { isBottomSheetVisible = false }
}
)
这是我编写的完整代码和一个可视化演示:
class MainActivity : ComponentActivity() {
@OptIn(ExperimentalMaterial3Api::class)
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {
MyApplicationTheme {
// A surface container using the 'background' color from the theme
Surface(
modifier = Modifier.fillMaxSize(),
color = MaterialTheme.colorScheme.background
) {
val scope = rememberCoroutineScope()
var isBottomSheetVisible by rememberSaveable { mutableStateOf(false) }
val sheetState = rememberModalBottomSheetState(
skipPartiallyExpanded = true
)
// A box with a simple button
// just to show the bottom sheet.
Box(
modifier = Modifier
.fillMaxSize()
.systemBarsPadding()
.padding(64.dp),
contentAlignment = Alignment.BottomCenter
) {
OutlinedButton(
onClick = {
scope.launch {
isBottomSheetVisible = true
sheetState.expand()
}
}
) {
Text(text = "Show")
}
}
BottomSheet(
isBottomSheetVisible = isBottomSheetVisible,
sheetState = sheetState,
onDismiss = {
scope.launch { sheetState.hide() }
.invokeOnCompletion { isBottomSheetVisible = false }
}
)
}
}
}
}
}
@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun BottomSheet(
isBottomSheetVisible: Boolean,
sheetState: SheetState,
onDismiss: () -> Unit
) {
if (isBottomSheetVisible) {
ModalBottomSheet(
onDismissRequest = onDismiss,
sheetState = sheetState,
containerColor = Color.Transparent,
contentColor = MaterialTheme.colorScheme.onSurface,
shape = RectangleShape,
dragHandle = null,
scrimColor = Color.Black.copy(alpha = .5f),
windowInsets = WindowInsets(0, 0, 0, 0)
) {
Box(
modifier = Modifier
.statusBarsPadding()
.fillMaxWidth()
.padding(8.dp),
contentAlignment = Alignment.Center
) {
FilledIconButton(
modifier = Modifier.size(48.dp),
onClick = onDismiss,
colors = IconButtonDefaults.filledIconButtonColors(
containerColor = MaterialTheme.colorScheme.background
)
) {
Icon(
imageVector = Icons.Rounded.Close,
contentDescription = "Hide the dialog."
)
}
}
Column(
modifier = Modifier
.navigationBarsPadding()
.padding(12.dp) // Outer padding
.clip(shape = RoundedCornerShape(24.dp))
.background(color = MaterialTheme.colorScheme.background)
.fillMaxWidth()
.padding(24.dp) // Inner padding
) {
Spacer(modifier = Modifier.height(16.dp))
OutlinedTextField(
modifier = Modifier.fillMaxWidth(),
value = "10th avenue, Some, State",
onValueChange = {},
label = { Text(text = "Delivery Address") },
readOnly = true,
shape = RoundedCornerShape(12.dp)
)
Spacer(modifier = Modifier.height(24.dp))
OutlinedTextField(
modifier = Modifier.fillMaxWidth(),
value = "09090606000",
onValueChange = {},
label = { Text(text = "Number we can call") },
readOnly = true,
shape = RoundedCornerShape(12.dp)
)
Spacer(modifier = Modifier.height(48.dp))
Row(
modifier = Modifier.fillMaxWidth(),
verticalAlignment = Alignment.CenterVertically,
horizontalArrangement = Arrangement.SpaceBetween
) {
OutlinedButton(
onClick = {},
content = { Text(text = "Pay on delivery") }
)
OutlinedButton(
onClick = {},
content = { Text(text = "Pay with card") }
)
}
}
}
}
}
编码快乐!🙌🏼