Yan*_*ick 6 android android-jetpack-compose
我想实现一个可以显示两个不同底部工作表的屏幕。由于ModalBottomSheetLayout只有一个片槽我决定改变sheetContent的ModalBottomSheetLayout动态使用selected状态时我要显示或者在两个片材(的全码)。
val sheetState = rememberModalBottomSheetState(initialValue = ModalBottomSheetValue.Hidden)
val (selected, setSelected) = remember(calculation = { mutableStateOf(0) })
ModalBottomSheetLayout(sheetState = sheetState, sheetContent = {
when (selected) {
0 -> Layout1()
1 -> Layout2()
}
}) {
Content(sheetState = sheetState, setSelected = setSelected)
}
Run Code Online (Sandbox Code Playgroud)
这适用于非常相似的工作表,但是一旦您向两个工作表布局中的任何一个添加更多复杂性,第一次按下按钮时工作表将不会显示,它只会在您按下按钮两次后显示可以在这里看到:

我有一个类似的用例,我需要显示 2-3 个堆叠的底页。我最终复制了 Compose BottomSheet 的大部分内容并添加了所需的行为:
enum class BottomSheetValue { SHOWING, HIDDEN }
@Composable
fun BottomSheet(
parentHeight: Int,
topOffset: Dp = 0.dp,
fillMaxHeight: Boolean = false,
sheetState: SwipeableState<BottomSheetValue>,
shape: Shape = bottomSheetShape,
backgroundColor: Color = MaterialTheme.colors.background,
contentColor: Color = contentColorFor(backgroundColor),
elevation: Dp = 0.dp,
content: @Composable () -> Unit
) {
val topOffsetPx = with(LocalDensity.current) { topOffset.roundToPx() }
var bottomSheetHeight by remember { mutableStateOf(parentHeight.toFloat())}
val scrollConnection = sheetState.PreUpPostDownNestedScrollConnection
BottomSheetLayout(
maxHeight = parentHeight - topOffsetPx,
fillMaxHeight = fillMaxHeight
) {
val swipeable = Modifier.swipeable(
state = sheetState,
anchors = mapOf(
parentHeight.toFloat() to BottomSheetValue.HIDDEN,
parentHeight - bottomSheetHeight to BottomSheetValue.SHOWING
),
orientation = Orientation.Vertical,
resistance = null
)
Surface(
shape = shape,
color = backgroundColor,
contentColor = contentColor,
elevation = elevation,
modifier = Modifier
.nestedScroll(scrollConnection)
.offset { IntOffset(0, sheetState.offset.value.roundToInt()) }
.then(swipeable)
.onGloballyPositioned {
bottomSheetHeight = it.size.height.toFloat()
},
) {
content()
}
}
}
@Composable
private fun BottomSheetLayout(
maxHeight: Int,
fillMaxHeight: Boolean,
content: @Composable () -> Unit
) {
Layout(content = content) { measurables, constraints ->
val sheetConstraints =
if (fillMaxHeight) {
constraints.copy(minHeight = maxHeight, maxHeight = maxHeight)
} else {
constraints.copy(maxHeight = maxHeight)
}
val placeable = measurables.first().measure(sheetConstraints)
layout(placeable.width, placeable.height) {
placeable.placeRelative(0, 0)
}
}
}
Run Code Online (Sandbox Code Playgroud)
TopOffset 例如允许将 BottomSheet 放置在 AppBar 下方:
BoxWithConstraints {
BottomSheet(
parentHeight = constraints.maxHeight,
topOffset = with(LocalDensity.current) {56.toDp()}
fillMaxHeight = true,
sheetState = yourSheetState,
) {
content()
}
}
Run Code Online (Sandbox Code Playgroud)
我是这样实现的。它看起来很简单,但我仍然不知道如何直接将参数传递给“mutableStateOf()”,我必须创建一个变量“content”
fun Screen() {
val bottomSheetState = rememberModalBottomSheetState(ModalBottomSheetValue.Hidden)
val scope = rememberCoroutineScope()
val content: @Composable (() -> Unit) = { Text("NULL") }
var customSheetContent by remember { mutableStateOf(content) }
ModalBottomSheetLayout(
sheetState = bottomSheetState,
sheetContent = {
customSheetContent()
}
) {
Column {
Button(
onClick = {
customSheetContent = { SomeComposable1() }
scope.launch { bottomSheetState.show() }
}) {
Text("First Button")
}
Button(
onClick = {
customSheetContent = { SomeComposable2() }
scope.launch { bottomSheetState.show() }
}) {
Text("Second Button")
}
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1818 次 |
| 最近记录: |