I'm trying to implement 2 different contents for `...
# compose
p
I'm trying to implement 2 different contents for
ModalBottomSheetLayout
and I'm having a weird effect, please see video. Sheet layout seems to visually collapse on start. Any ideas? Source code in thread.
Copy code
@Preview
@Composable
fun Screen() {
    val scope = rememberCoroutineScope()
    var isSheetA by remember { mutableStateOf(true) }
    val sheetState = rememberModalBottomSheetState(ModalBottomSheetValue.Expanded)

    fun openSheet(isA: Boolean) = scope.launch {
        isSheetA = isA
        sheetState.expand()
    }

    ModalBottomSheetLayout(
        sheetState = sheetState,
        sheetElevation = 0.dp,
        sheetContent = {
            if (isSheetA) SheetA() else SheetB()
        }
    ) {
        Content(
            onOpenA = {
                openSheet(true)
            },
            onOpenB = {
                openSheet(false)
            },
        )
    }

}

@Composable
private fun SheetA() = Column {
    // Just added few composables, to increase complexity, otherwise it works fine
    Row(modifier = Modifier.fillMaxWidth()) {
        Text(text = "open A")
        Text(text = "open A")
    }
    Row(modifier = Modifier.fillMaxWidth()) {
        Text(text = "open A")
        Text(text = "open A")
    }
    Row(modifier = Modifier.fillMaxWidth()) {
        Text(text = "open A")
        Text(text = "open A")
    }
}

@Composable
private fun SheetB() = Sheet(height = 600.dp, color = Color.Green)

@Composable
private fun Sheet(height: Dp, color: Color) = Box(
    modifier = Modifier
        .fillMaxWidth()
        .height(height)
        .background(color)
)

@Composable
private fun Content(onOpenA: () -> Unit, onOpenB: () -> Unit) = Column(
    modifier = Modifier.fillMaxSize()
) {
    Button(onClick = onOpenA) {
        Text(text = "open A")
    }
    Button(onClick = onOpenB) {
        Text(text = "open B")
    }
}
i
The
initialState
you're passing into
rememberModalBottomSheetState
is
ModalBottomSheetValue.Expanded
which means the sheet is 'visible at full height' (compared to
HalfExpanded
with the 50% of the available height or
Hidden
which is not visible by default), but your video seems to show you starting in the 'no bottom sheet visible' kind of state, which seems to imply that
Hidden
is more correct?
It looks like the bottom sheet is animating down from the fully expanded height to the height of the content
p
sry, OP video code is a tiny bit different, since it seems like it's not possible to update the video
even if I change initial state to Hidden, it still has same effect, when I swap between sheets
i
Well now it looks like your first transition is working fine, which wasn't the case in your first video
it slides in from bottom vs coming down from the top
p
sorry for confusing you, please pay attention on my latest video, when I try to expand() white sheet, after green one is closed. This is the side effect that I want to fix.
it works ok, if I use
sheetState.show()
, but it's not ideal, since would need to have it fully expanded
i
Nope, not confused. I think you just have multiple problems going on which is making it more difficult to see what ModalBottomSheetLayout is actually doing
ModalBottomSheetLayout works by animating the anchor point - the top of the sheet
So when you start at
Hidden
and
show()
, it animates up to the fully expanded height of your content
Once you dismiss that sheet, you should be back in the
Hidden
state - i.e., animating up from the bottom when you next
show
your sheet
But clearly, at some point in that green to white transition, it looks like the
ModalBottomSheetLayout
appears to be animating from the
Expanded
height of the green sheet to the
Expanded
height of the white sheet
which, since the green sheet is taller, means it animates down to the white sheet, rather than the white sheet appearing up from the bottom
If you want to act as if the green sheet is being hidden and the white sheet is replacing it, then it sounds more like you need to
hide()
, swap contents, then
show()
- as
hide()
and
show()
are suspending methods, they'll only resume after they complete (i.e., you won't swap contents until the
hide
completes and the anchor is back at the bottom)
p
hm, I see
I'm still not sure why it has same effect, even if you wait 10 seconds or something, for big sheet to close tough
I wonder if your
show()
runs (and sets the anchors based on the old height) for a frame before the new height comes in
It seems like you have the reproduction project, so filing an issue against Compose would be the best way to get the author of ModalBottomSheetLayout to confirm whether that is actually the case: https://issuetracker.google.com/issues/new?component=612128
2
✔️ 1
p
Ok, will do. Thank you for your help!