4

I currently display a Bottom Sheet through a BottomSheetScaffold and want to collapse it when the user clicks outside the Bottom Sheet. Is there a way to detect the click outside of the Bottom Sheet?

This is the screen with my BottomSheetScaffold:

@ExperimentalMaterialApi
@ExperimentalMaterial3Api
@Composable
fun HomeScreen() {
    val bottomSheetScaffoldState = rememberBottomSheetScaffoldState(
        bottomSheetState = BottomSheetState(BottomSheetValue.Collapsed)
    )
    val coroutineScope = rememberCoroutineScope()

    BottomSheetScaffold(
        scaffoldState = bottomSheetScaffoldState,
        sheetContent = {
            Box(
                Modifier
                    .fillMaxWidth()
                    .fillMaxHeight(0.9f)
            ) {
                Text("Hello from Sheet")
            }
        },
        sheetShape = RoundedCornerShape(
            topStart = Spacing.l,
            topEnd = Spacing.l
        ),
        sheetPeekHeight = LocalConfiguration.current.screenHeightDp.dp * 0.15f,
        sheetBackgroundColor = MaterialTheme.colorScheme.surface,
    ) {
        Scaffold() {
            Button(
                onClick = {
                    coroutineScope.launch {
                        if (bottomSheetScaffoldState.bottomSheetState.isCollapsed) {
                            bottomSheetScaffoldState.bottomSheetState.expand()
                        } else {
                            bottomSheetScaffoldState.bottomSheetState.collapse()
                        }
                    }
                },
            ) {
                Text("Toggle Sheet")
            }
        }

    }
}

This is a visualization of the area in which I want to detect the click if the Bottom Sheet is expanded.

enter image description here

JonasLevin
  • 1,592
  • 1
  • 20
  • 50

4 Answers4

11

You can add the pointerInput modifier with detectTapGestures to your Scaffold:

   Scaffold( modifier =
        Modifier.pointerInput(Unit) {
            detectTapGestures(onTap = {
                coroutineScope.launch {
                    if (bottomSheetScaffoldState.bottomSheetState.isCollapsed) {
                        bottomSheetScaffoldState.bottomSheetState.expand()
                    } else {
                        bottomSheetScaffoldState.bottomSheetState.collapse()
                    }
                }
            })
    }){
       //.....
    }
Gabriele Mariotti
  • 320,139
  • 94
  • 887
  • 841
4

I had the same problem using the BottomSheetScaffold, and I changed to the ModalBottomSheetLayout that already has that behavior by default. I hope this could help anybody with the same problem

Jaydeep parmar
  • 561
  • 2
  • 15
1

I adapted the answer with the last version of material 3:

val scope = rememberCoroutineScope()
val scaffoldState = rememberBottomSheetScaffoldState(bottomSheetState = rememberStandardBottomSheetState(skipHiddenState = false))

BottomSheetScaffold(
    scaffoldState = scaffoldState,
    sheetContent = {},
    modifier =
    Modifier.pointerInput(Unit) {
        detectTapGestures(onTap = {
            scope.launch {
                if (scaffoldState.bottomSheetState.isVisible) {
                    scaffoldState.bottomSheetState.hide()
                }
            }
        })
    }
)  
CmoiJulien
  • 659
  • 8
  • 6
0

try using ModalBottomSheetLayout

visit this how to implement modalbottomsheet

Alok Singh
  • 35
  • 10