Reputation: 191
I am trying to have a way to show a BottomSheet from everywhere within my app, for that I use the BottomSheetScaffold
and a LiveData object that holds the current composable function which is observed as state:
val sheetContent by MusicHub.state.bottomSheet.getContent().observeAsState()
BottomSheetScaffold(
modifier = Modifier
.fillMaxSize(),
scaffoldState = bottomSheetScaffoldState,
sheetPeekHeight = 0.dp,
sheetContent = sheetContent!!
)
I use the BottomSheet as a context menu in my app. For example when i longClick on a playlist in my app it sets the content of the BottomSheet and shows it like this:
PlaylistItem(
// ...
onLongClick = {
// Set the LiveData composable
MusicHub.state.bottomSheet.setContent {
PlaylistContextMenuTest(playlist!!, viewModel)
}
// Expand BottomSheet
scope.launch {
MusicHub.state.bottomSheet.expand()
}
}
)
In general this works but the first time the BottomSheet gets expanded it shows for a split second before it disappears at the bottom again. Here is a small GIF:
My guess is that somehow the size of the BottomSheet is not recalculated yet and hence it only works in the next recomposition. Coming from web dev i would say its a typical case of requestAnimationFrame but i don't quite know how to solve this issue in compose.
Edit:
PlaylistContextMenuTest code:
@Composable
fun PlaylistContextMenuTest(playlist: Playlist, viewModel: LibraryViewModel = activityViewModel()){
val scrollState = rememberScrollState()
Column(
modifier = Modifier
.fillMaxWidth()
.navigationBarsPadding()
// TODO: Replace that with a percentage of the screen height
.heightIn(max = 384.dp)
.verticalScroll(scrollState),
content = {
ContextMenu {
repeat(4){
addOption(R.drawable.ic_delete_black_24dp, "Delete"){
Timber.d("Delete Playlist")
viewModel.deletePlaylist(playlist)
}
}
}
}
)
}
Full ContextMenu source: (https://pastebin.com/sg4ed96L)
Upvotes: 5
Views: 10928
Reputation: 969
You seem to be right. The first time it seems to be re-calculating the BottomSheet's height.
As this does not change on the second try, it will then be displayed.
Does this answer help you?
It seems to work out quite okay for BottomSheetScaffold, but not for ModalBottomSheetLayout (the thing I was looking for as you can see in the comments of the linked answer).
Edit: Accompanist's Navigation Material is also worth a look.
Upvotes: 3
Reputation: 191
This issue has been resolved with a new release of jetpack compose. I am not sure if it was beta 8 or 9 but everything works as intended now.
Upvotes: 0