androidandroid-jetpack-composeandroid-dialogandroid-bottomsheetdialog

Modal Bottom Sheet not opening inside Dialog


Upon clicking a FAB, the app opens a Dialog with a camera icon in it, including text fields. Clicking the icon does not open the ModalBottomSheetLayout inside the Dialog as it should; It opens it in the parent screen that contains the FAB. How can make it open inside the Dialog?

Screen Recording

enter image description here

Main Screen Composable:

@OptIn(ExperimentalMaterialApi::class)
@Composable
fun AddItemDialogWithModalSheet(
    onDismiss: () -> Unit,
) {
    val sheetState = rememberModalBottomSheetState(initialValue = ModalBottomSheetValue.Hidden)
    val scope = rememberCoroutineScope()

    ModalBottomSheetLayout(
        sheetContent = {
            Column() {
            Text(text = "Testing")
            Text(text = "Testing")
            Text(text = "Testing")
            Text(text = "Testing")
            Text(text = "Testing")
            Text(text = "Testing")
        }
        },
        sheetState = sheetState,
    ) {
        AddItemDialog(
            onConfirmClicked = { /*TODO*/ },
            onDismiss = onDismiss,
            onCameraClick = {
                scope.launch {
                    sheetState.show()
                }
            }
        )
    }
}

Dialog Composable:

@OptIn(ExperimentalComposeUiApi::class)
@Composable
fun AddItemDialog(
    onConfirmClicked: () -> Unit,
    onDismiss: () -> Unit,
    onCameraClick: () -> Unit
) {
    val nameText = rememberSaveable { mutableStateOf("") }
    val quantityText = rememberSaveable { mutableStateOf("") }
    val unitText = rememberSaveable { mutableStateOf("") }
    val ppuText = rememberSaveable { mutableStateOf("") }
    val notesText = rememberSaveable { mutableStateOf("") }
    var categoryText = rememberSaveable { mutableStateOf("") }

    Dialog(
        onDismissRequest = onDismiss,
        properties = DialogProperties(usePlatformDefaultWidth = false),
    ) {
        Surface(
            shape = MaterialTheme.shapes.medium,
            color = MaterialTheme.colors.surface,
            modifier = Modifier
                .width(LocalConfiguration.current.screenWidthDp.dp * 0.96f)
                .padding(4.dp)
        ) { 
            ...
            
             Row(
                verticalAlignment = Alignment.CenterVertically,
                horizontalArrangement = Arrangement.Center,
                modifier = Modifier
                    .fillMaxWidth()
                    .requiredHeight(70.dp)
                    .padding(10.dp)
                ) {

                    Icon(
                        painterResource(id = R.drawable.ic_baseline_photo_camera_24),
                        contentDescription = "Add Item Picture",
                        modifier = Modifier
                            .size(40.dp).clickable(onClick = {
                                onCameraClick()  //this code does not open the bottom sheet
                            })
                    )

                  }
          }
      } 
}

Solution

  • I don't think this is a good idea in terms of UX.

    My suggestion is follow the Material Design guidelines and use the Full Screen Dialog. See what the documentation says:

    Full-screen dialogs may be used for content or tasks that meet any of these criteria:

    • Dialogs that include components which require keyboard input, such as form fields;
    • When changes aren’t saved instantly;
    • When components within the dialog open additional dialogs.

    Your UI matches all the criteria to use a full-screen dialog.