https://kotlinlang.org logo
#compose-android
Title
# compose-android
q

Qamar Khan

03/28/2023, 9:33 AM
I am using a navigation bar, but the issue I am facing is that when the bottom sheet is open, it appears behind the bottom navigation bar. I would like the bottom sheet to appear above the navigation bar or hide when the sheet is open. Please note that I have a composable screen called ServiceScreen where I am writing the code for the bottom sheet. Here is the code for the MainScreen composable function where the bottom navigation bar is implemented: see thread for code
@Composable fun MainScreen(navController: NavHostController) { var showBottomBar by rememberSaveable { mutableStateOf(true) } Scaffold( topBar = { }, bottomBar = { if (showBottomBar) { BottomAppBar( modifier = Modifier.fillMaxWidth(), backgroundColor = Color.White ) { BottomNavigationBar(navController) } } }, content = { padding -> Box(modifier = Modifier.padding(padding)) { Navigation(navController) } }, ) }
i want to achieve this basically
t

Tim Malseed

03/28/2023, 9:35 AM
Where is your bottom sheet code?
q

Qamar Khan

03/28/2023, 9:35 AM
Copy code
@SuppressLint("StateFlowValueCalledInComposition")
@OptIn(ExperimentalMaterialApi::class)
@Composable
fun ServiceScreen(userViewModel: ServicesViewModel) {
    // val state by userViewModel.uiState.collectAsState()

    val modalSheetState = rememberModalBottomSheetState(
        initialValue = ModalBottomSheetValue.Hidden,
        confirmStateChange = { it != ModalBottomSheetValue.HalfExpanded }
    )
    val roundedCornerRadius = 20.dp
    val sheetShape =
        RoundedCornerShape(topStart = roundedCornerRadius, topEnd = roundedCornerRadius)

    val coroutineScope = rememberCoroutineScope()
    val closeSheet: () -> Unit = {
        coroutineScope.launch {
            modalSheetState.hide()
        }
    }
    val openSheet: () -> Unit = {
        coroutineScope.launch {
            if (modalSheetState.isVisible) {
                modalSheetState.hide()
            } else {
                modalSheetState.animateTo(ModalBottomSheetValue.Expanded)
            }
        }
    }

    GenericBottomSheet(
        sheetState = modalSheetState,
        sheetShape = sheetShape,
        sheetContent = {
            ShowLoginOrRegisterBottomSheet(
                closeSheet = closeSheet,
                viewModel = userViewModel
            )
        },
        mainContent = {
            ScreenContent(
                openSheet = openSheet,
                userViewModel = userViewModel
            )
        }
    )
}
@Tim Malseed
t

Tim Malseed

03/28/2023, 9:37 AM
In the code above, I can’t tell how MainScreen and ServiceScreen are related. Is one of them nested inside the other one somehow?
q

Qamar Khan

03/28/2023, 9:39 AM
Copy code
content = { padding -> // We have to pass the scaffold inner padding to our content. That's why we use Box.
    Box(modifier = Modifier.padding(padding)) {
       Navigation(navController)
    }
}
as you see navigation handle the screen content in main activity, this is the below code is used to render any composable screen
Copy code
@Composable
fun Navigation(navController: NavHostController){
    NavHost(
        navController = navController,
        startDestination = MainDirection.splash.destination

    ) {
        composable(MainDirection.splash.destination) {
            SplashScreen(hiltViewModel(), navController = navController)
        }
        composable(MainDirection.personalise.destination) {
            PersonaliseScreen(hiltViewModel(), navController = navController)
        }
t

Tim Malseed

03/28/2023, 9:41 AM
OK, so
Navigation()
lives inside
MainScreen()
. And then, where does
ServiceScreen()
live?
q

Qamar Khan

03/28/2023, 9:41 AM
yes exectly and ServiceScreen also lives in navigation
t

Tim Malseed

03/28/2023, 9:42 AM
So it’s one of your navigation destinations?
q

Qamar Khan

03/28/2023, 9:42 AM
yes its my navigation destination
Copy code
composable(DashboardDirection.services.destination){
    ServiceScreen(hiltViewModel())
}
t

Tim Malseed

03/28/2023, 9:44 AM
So, it sounds like you want to call
showBottomBar = false
when your nav destination is
DashboardDirection.services.destination
Maybe you could add an
OnDestinationChangedListener
to your
NavHostController
and hide the bottom sheet when the destination is ‘services’
q

Qamar Khan

03/28/2023, 9:47 AM
Nope i have a bottomsheet on service screen and when bottom sheet is opened, then i want its should be above bottom navigation or else i can hide navigation bar.. i attached image above you can check what i want
t

Tim Malseed

03/28/2023, 9:48 AM
I would like the bottom sheet to appear above the navigation bar or hide when the sheet is open
So you don’t want it to hide when the sheet is open?
o

Oleksandr Balan

03/28/2023, 1:05 PM
I think you want to use another component: Modal Bottom Sheet instead of the standard one. In Material3 version of ✏️ there is a fairly new implementation of the ModalBottomSheet. Which is a little bit buggy at the moment, see issue tracker. In Material2 version there is only a ModalBottomSheetLayout implementation, which is hard to use in destinations inside the bottom navigation bar. If you do not use M3 library, or M3 bottom sheet does not work correctly in your case, you could try this ModalSheet library, which basically wraps the
ModalBottomSheetLayout
ands shows it in the custom fullscreen popup to ensure that bottom sheet is displayed above other UI.
d

dewildte

03/28/2023, 4:44 PM
You could also treat the BottomSheet as a navigation destination.
Accompanist has some code that does this kind of thing too: https://google.github.io/accompanist/navigation-material/#bottom-sheet-destinations
q

Qamar Khan

03/28/2023, 6:29 PM
@Oleksandr Balan Thanks for your suggestion, it works for me https://github.com/oleksandrbalan/modalsheet i just get the specific code from library and used that according to my requirement, once again thanks alot. Appreciate your time.
@Oleksandr Balan @dewildte @Tim Malseed i really Appreciate your time and effort, thanks to all 🙂
74 Views