skydoves / FlexibleBottomSheet

šŸ¬ Advanced Compose Multiplatform bottom sheet for segmented sizing, non-modal type, and allows interaction behind the bottom sheet similar to Google Maps.
Apache License 2.0
687 stars 30 forks source link

Implementing Bottom Sheet Scrim Display Upon Expansion #15

Open ghasemdev opened 6 months ago

ghasemdev commented 6 months ago

Is your feature request related to a problem?

When we pull down the bottom sheet and hold it, even though the bottom sheet exists, it is possible to click behind it and navigate to another page, and then reopen the bottom sheet again, even if it is a modal bottom sheet.

Describe the solution you'd like:

Describe alternatives you've considered:

skydoves commented 6 months ago

Hey @ghasemdev, would you elaborate on this? It sounds like this issue should be prevented from the user side. Does this work different from the Material3's ModalBottomSheet?

ghasemdev commented 6 months ago

I have tested my own scenario, and it appears that you have managed the dragging of the bottom sheet, and clicking on the page is not functional. However, I am curious to know why I still cannot click on the page even if I omit the if-statement related to the absence of the bottom sheet.

var shouldShowBottomSheet by rememberSaveable { mutableStateOf(false) }
val coroutineScope = rememberCoroutineScope()
val bottomSheetState = rememberFlexibleBottomSheetState(
    containSystemBars = true,
    isModal = true,
)

Column(
    modifier = Modifier.fillMaxSize(),
    horizontalAlignment = Alignment.CenterHorizontally
) {
    Button(
        onClick = {
            Toast.makeText(this@MainActivity, "Show Toast", Toast.LENGTH_SHORT).show()
        }
    ) {
        Text(text = "Toast")
    }
     Button(
         onClick = {
             coroutineScope.launch {
                 shouldShowBottomSheet = true
                 delay(50)
                 bottomSheetState.intermediatelyExpand()
             }
         }
    ) {
        Text(text = "Show Bottom Sheet")
    }
}

if (shouldShowBottomSheet) {
    FlexibleBottomSheet(
        onDismissRequest = {
            shouldShowBottomSheet = false
        },
        sheetState = bottomSheetState,
        scrimColor = Color.Black.copy(.7f),
        containerColor = Color.LightGray
    ) {
       Column(
           modifier = Modifier.fillMaxWidth(),
           horizontalAlignment = Alignment.CenterHorizontally
       ) {
            Text(text = "sheet")
          } 
      }
}
ghasemdev commented 6 months ago

https://github.com/skydoves/FlexibleBottomSheet/assets/65798992/13ee6c15-b3f4-4d80-a0d1-4fd2384c1251

@skydoves It seems like in the XML, the scrim doesnā€™t disappear when the bottom sheet is in the hiding process. šŸ¤”

ghasemdev commented 6 months ago

I have tested my own scenario, and it appears that you have managed the dragging of the bottom sheet, and clicking on the page is not functional. However, I am curious to know why I still cannot click on the page even if I omit the if-statement related to the absence of the bottom sheet.

var shouldShowBottomSheet by rememberSaveable { mutableStateOf(false) }
val coroutineScope = rememberCoroutineScope()
val bottomSheetState = rememberFlexibleBottomSheetState(
    containSystemBars = true,
    isModal = true,
)

Column(
    modifier = Modifier.fillMaxSize(),
    horizontalAlignment = Alignment.CenterHorizontally
) {
    Button(
        onClick = {
            Toast.makeText(this@MainActivity, "Show Toast", Toast.LENGTH_SHORT).show()
        }
    ) {
        Text(text = "Toast")
    }
     Button(
         onClick = {
             coroutineScope.launch {
                 shouldShowBottomSheet = true
                 delay(50)
                 bottomSheetState.intermediatelyExpand()
             }
         }
    ) {
        Text(text = "Show Bottom Sheet")
    }
}

if (shouldShowBottomSheet) {
    FlexibleBottomSheet(
        onDismissRequest = {
            shouldShowBottomSheet = false
        },
        sheetState = bottomSheetState,
        scrimColor = Color.Black.copy(.7f),
        containerColor = Color.LightGray
    ) {
       Column(
           modifier = Modifier.fillMaxWidth(),
           horizontalAlignment = Alignment.CenterHorizontally
       ) {
            Text(text = "sheet")
          } 
      }
}

My implementation had a problem, but after reading the Material Design 3 documentation, I realized the need for an if-statement and a boolean variable.

var shouldShowBottomSheet by rememberSaveable { mutableStateOf(false) }
val coroutineScope = rememberCoroutineScope()
val bottomSheetState = rememberFlexibleBottomSheetState(
    containSystemBars = true,
    isModal = true,
)

Column(
    modifier = Modifier.fillMaxSize(),
    horizontalAlignment = Alignment.CenterHorizontally
) {
    Button(
        onClick = {
            Toast.makeText(this@MainActivity, "Show Toast", Toast.LENGTH_SHORT).show()
        }
    ) {
        Text(text = "Toast")
    }
     Button(
         onClick = {
              shouldShowBottomSheet = true
         }
    ) {
        Text(text = "Show Bottom Sheet")
    }
}

if (shouldShowBottomSheet) {
    FlexibleBottomSheet(
        onDismissRequest = {
            shouldShowBottomSheet = false
        },
        sheetState = bottomSheetState,
        scrimColor = Color.Black.copy(.7f),
        containerColor = Color.LightGray
    ) {
       Column(
           modifier = Modifier.fillMaxWidth(),
           horizontalAlignment = Alignment.CenterHorizontally
       ) {
            Button(
                  onClick = {
                    coroutineScope.launch { bottomSheetState.hide() }.invokeOnCompletion {
                      if (!bottomSheetState.isVisible) {
                        showBottomSheet = false
                      }
                    }
                  }
                ) {
                  Text(text = "Hide")
                }
          } 
      }
}
ghasemdev commented 6 months ago

Another question has arisen for me: how can one disable the ā€˜dragGestureā€™? In the Material 2 bottom sheet, we had the capability to disable this feature to prevent the bottom sheet from closing when dragged.

ghasemdev commented 6 months ago

Another question has arisen for me: how can one disable the ā€˜dragGestureā€™? In the Material 2 bottom sheet, we had the capability to disable this feature to prevent the bottom sheet from closing when dragged.

For now, I am using this method.

 val bottomSheetState = rememberModalBottomSheetState(
        skipPartiallyExpanded = true,
        confirmValueChange = {
          // Prevent collapsing by swipe down gesture
          if (!isDraggable) it != FlexibleSheetValue.IntermediatelyExpanded else true
        }
 )