Reputation: 35
I'm working on a Jetpack Compose project and using the ModalBottomSheet from Material3 to display a bottom sheet when a FloatingActionButton is clicked. However, I'm experiencing issues with the sheet not animating smoothly when it appears or disappears. The animation seems to lag or isn't as fluid as expected.
Here's a summary of what I'm doing:
I have a MainScreen composable where the sheet visibility is controlled by a Boolean state. When the state is true, a custom bottom sheet (MyBottomSheet) is shown. The bottom sheet contains a TextField, and I'm trying to automatically focus on it when the sheet appears. The ModalBottomSheet is using a rememberModalBottomSheetState to manage its state. Despite following the standard implementation, the animation isn't smooth. I would greatly appreciate any advice on what might be causing this issue or how to improve the smoothness of the animations.
MyTextField.kt
@Composable
fun MyTextField(modifier: Modifier = Modifier) {
var text by remember { mutableStateOf("") }
val focusRequester = remember { FocusRequester() }
TextField(
value = text,
onValueChange = { text = it },
label = { Text("Label") },
modifier = modifier
.fillMaxWidth()
.focusRequester(focusRequester)
)
LaunchedEffect(Unit) {
focusRequester.requestFocus()
}
}
MyBottomSheet.kt
@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun MyBottomSheet(modifier: Modifier, onDismiss: () -> Unit) {
val modalBottomSheetState = rememberModalBottomSheetState()
val coroutineScope = rememberCoroutineScope()
LaunchedEffect(modalBottomSheetState.isVisible) {
if (modalBottomSheetState.isVisible) {
coroutineScope.launch {
modalBottomSheetState.show()
}
}
}
ModalBottomSheet(
onDismissRequest = { onDismiss() },
sheetState = modalBottomSheetState,
dragHandle = { BottomSheetDefaults.DragHandle() },
modifier = modifier,
content = {
MyTextField()
}
)
}
MainScreen.kt
@Preview(showBackground = true)
@Composable
fun MainScreen() {
var showSheet by remember { mutableStateOf(false) }
if (showSheet) {
MyBottomSheet(modifier = Modifier) {
showSheet = false
}
}
Box(
modifier = Modifier
.padding(all = 8.dp)
.fillMaxSize()
) {
MyFloatingActionButton(
onClick = {
showSheet = true
},
modifier = Modifier
.align(Alignment.BottomEnd)
.padding(bottom = 80.dp)
.padding(end = 10.dp)
)
}
}
Upvotes: 2
Views: 893
Reputation: 225
You can use the below predefined state and assign the state directly to your sheetState, SwipeableDefaults.AnimationSpec is the main thing to be added to handle the smooth transition.
val modalBottomSheetState =
rememberModalBottomSheetState(initialValue = ModalBottomSheetValue.Expanded,
animationSpec = SwipeableDefaults.AnimationSpec,
confirmValueChange = { false },
skipHalfExpanded = true)
Upvotes: 0
Reputation: 1552
I'm not sure if these changes will fix the issue because you didn't provide a complete example to test.
Since you're already controlling the bottom sheet's visibility with a state variable, you don't need to do it programmatically as well. You can remove or comment out that part of the code, like this:
@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun MyBottomSheet(modifier: Modifier, onDismiss: () -> Unit) {
val modalBottomSheetState = rememberModalBottomSheetState()
// val coroutineScope = rememberCoroutineScope()
//
// LaunchedEffect(modalBottomSheetState.isVisible) {
// if (modalBottomSheetState.isVisible) {
// coroutineScope.launch {
// modalBottomSheetState.show()
// }
// }
// }
ModalBottomSheet(
onDismissRequest = { onDismiss() },
sheetState = modalBottomSheetState,
//dragHandle = { BottomSheetDefaults.DragHandle() }, // Not needed, this is the default value
modifier = modifier,
content = {
MyTextField()
}
)
}
Another option to try is removing the auto-focus on the TextField. That might be causing the animation issue.
I hope this helps fix the problem.
Upvotes: 0