0

Based on what was answered in this question (Open ModalSheetLayout on TextField focus instead of Keyboard) and the exchange of comments I did with @Abhimanyu, I was able to get the ModalBottomSheetLayout to appear when I click on one of the TextFields,but I found another problem. As you can see in the image below, the ModalBottomSheetLayout is appearing behind the BottomNavigation and it is not supposed to. Is there any way I can show ModalBottomSheetLayout in front of BottomNavigation or hide BottomNavigation while ModalBottomSheet is open?

enter image description here

ModalBottomSheetLayout screen code:

    @ExperimentalMaterialApi
@Preview
@Composable
fun ProfileScreen() {
    var profileModalBottomSheetType by remember { mutableStateOf(ProfileModalBottomSheetType.NONE) }
    val modalBottomSheetState = rememberModalBottomSheetState(ModalBottomSheetValue.Hidden)
    val coroutineScope = rememberCoroutineScope()

    if (modalBottomSheetState.currentValue != ModalBottomSheetValue.Hidden) {
        DisposableEffect(Unit) {
            onDispose {
                profileModalBottomSheetType = ProfileModalBottomSheetType.NONE
            }
        }
    }

    ModalBottomSheetLayout(
        sheetState = modalBottomSheetState,
        sheetShape = RoundedCornerShape(topStart = 13.dp, topEnd = 13.dp),
        sheetContent = {
            Box(
                modifier = Modifier
                    .padding(top = 10.dp)
                    .height(10.dp)
                    .width(100.dp)
                    .background(
                        color = Color.LightGray,
                        shape = RoundedCornerShape(4.dp)
                    )
            )

            when (profileModalBottomSheetType) {
                ProfileModalBottomSheetType.SELECT_RATE -> {
                    SelectRateModalBottomSheet(listOf("Exact Rate", "Range"))
                }
                else -> {}
            }
        }
    ) {
        LazyColumn(
            modifier = Modifier
                .width(320.dp)
        ) {
            item {
                HeightSpacer(40.dp)

                Box(
                    modifier = Modifier.fillMaxSize(),
                    contentAlignment = Alignment.Center
                ) {
                    Image(
                        painter = painterResource(id = R.drawable.ic_clearjobs_logo_2x),
                        contentDescription = null
                    )
                }

                HeightSpacer(47.dp)

                Column(
                    modifier = Modifier
                        .width(320.dp)
                        .padding(start = 20.dp, end = 20.dp),
                    horizontalAlignment = Alignment.CenterHorizontally
                ) {
                    Text(
                        text = "Profile Light Title",
                        style = TextStyle32Light,
                        textAlign = TextAlign.Center
                    )

                    Text(
                        text = "Profile Bold Title",
                        style = TextStyle32Bold,
                        textAlign = TextAlign.Center
                    )
                }

                HeightSpacer(47.dp)

                Column(
                    modifier = Modifier
                        .background(
                            shape = RoundedCornerShape(
                                topStart = 13.dp,
                                topEnd = 13.dp
                            ), color = Color.White
                        )
                        .padding(bottom = 140.dp)
                        .width(320.dp)
                ) {
                    Text(
                        text = stringResource(id = R.string.your_profile),
                        style = TextStyle28Bold,
                        modifier = Modifier.padding(
                            top = 40.dp,
                            start = 20.dp,
                            bottom = 30.dp
                        )
                    )

                    Text(
                        text = stringResource(id = R.string.salary_range),
                        style = TextStyle28Bold,
                        modifier = Modifier.padding(
                            top = 40.dp,
                            start = 20.dp,
                            bottom = 30.dp
                        )
                    )

                    Box {
                        LightBlueBorderTextField(
                            title = "Rate",
                            initialState = "Exact Rate",
                            textFieldTextStyle = TextStyle16BlackOpacity50Normal,
                            enabled = false
                        ) { innerTextField ->
                            Row(verticalAlignment = Alignment.CenterVertically) {
                                Box(
                                    modifier = Modifier
                                        .weight(1f)
                                        .padding(start = Dimen10)
                                ) {
                                    innerTextField()
                                }
                            }
                        }

                        Box(
                            modifier = Modifier
                                .matchParentSize()
                                .alpha(0f)
                                .clickable(
                                    onClick = {
                                        profileModalBottomSheetType =
                                            ProfileModalBottomSheetType.SELECT_RATE
                                        toggleModalBottomSheetState(
                                            coroutineScope = coroutineScope,
                                            modalBottomSheetState = modalBottomSheetState,
                                        )
                                    }
                                )
                        )
                    }
                }
            }
        }
    }
}

@Composable
fun SelectRateModalBottomSheet(options: List<String>) {
    LazyColumn(
        modifier = Modifier.padding(
            start = 20.dp,
            end = 20.dp,
            top = 15.dp,
            bottom = 15.dp
        )
    ) {
        items(options.size) { optionIndex ->
            val option = options[optionIndex]

            Row(
                verticalAlignment = Alignment.CenterVertically,
                modifier = Modifier.padding(start = 10.dp, end = 10.dp, bottom = 15.dp)
            ) {
                Box(Modifier.weight(1f)) {
                    Text(text = option, style = TextStyle16BlackOpacity50Normal)
                }

                RadioButton(
                    selected = false,
                    onClick = { /*TODO*/ },
                    modifier = Modifier
                        .width(20.dp)
                        .height(20.dp)
                )
            }

            if (optionIndex != options.lastIndex) {
                Divider(color = Color.DarkGray, thickness = 1.dp)
                HeightSpacer(dimen = 15.dp)
            }
        }
    }
}

@Composable
fun HeightSpacer(dimen: Dp) {
    Spacer(modifier = Modifier.height(dimen))
}

@Preview
@Composable
fun LightBlueBorderTextField(
    title: String = "",
    initialState: String = "",
    textFieldTextStyle: TextStyle = TextStyle18Normal,
    enabled: Boolean = true,
    decorationBox: @Composable (innerTextField: @Composable () -> Unit) -> Unit = { innerTextField ->
        Box(
            Modifier.padding(start = Dimen10),
            contentAlignment = Alignment.CenterStart
        ) {
            innerTextField()
        }
    }
) {
    Column {
        val state = remember { mutableStateOf(TextFieldValue(initialState)) }

        if (title.isNotEmpty()) {
            Text(
                text = title,
                style = TextStyle16BlackBold,
                modifier = Modifier.padding(
                    top = Dimen40,
                    start = Dimen30,
                    bottom = Dimen10
                )
            )
        } else {
            HeightSpacer(Dimen40)
        }

        CustomTextField(
            state = state,
            modifier = Modifier
                .height(Dimen45)
                .padding(start = Dimen20, end = Dimen20)
                .border(
                    width = Dimen1,
                    color = LightBlue,
                    shape = RoundedCornerShape(Dimen13)
                )
                .background(Color.White, RoundedCornerShape(Dimen13))
                .fillMaxWidth(),
            textStyle = textFieldTextStyle,
            decorationBox = decorationBox,
            enabled = enabled
        )
    }
}

@Composable
fun CustomTextField(
    state: MutableState<TextFieldValue>,
    modifier: Modifier,
    textStyle: TextStyle = TextStyle18Normal,
    decorationBox: @Composable (innerTextField: @Composable () -> Unit) -> Unit,
    enabled: Boolean = true
) {
    BasicTextField(
        modifier = modifier,
        value = state.value,
        onValueChange = { value -> state.value = value },
        singleLine = true,
        textStyle = textStyle,
        decorationBox = decorationBox,
        enabled = enabled
    )
}

@ExperimentalMaterialApi
fun toggleModalBottomSheetState(
    coroutineScope: CoroutineScope,
    modalBottomSheetState: ModalBottomSheetState,
    action: (() -> Unit)? = null,
) {
    coroutineScope.launch {
        if (!modalBottomSheetState.isAnimationRunning) {
            if (modalBottomSheetState.isVisible) {
                modalBottomSheetState.hide()
            } else {
                modalBottomSheetState.show()
            }
        }
        action?.invoke()
    }
}

internal enum class ProfileModalBottomSheetType {
    NONE,
    SELECT_JOB_KEYWORDS,
    SELECT_WORK_LOCATIONS,
    SELECT_TAGS,
    SELECT_RATE,
    SELECT_SALARY_PERIOD
}

Navigation code:

import androidx.compose.foundation.ExperimentalFoundationApi
import androidx.compose.material.ExperimentalMaterialApi
import androidx.compose.runtime.Composable
import androidx.hilt.navigation.compose.hiltViewModel
import androidx.navigation.NavHostController
import androidx.navigation.NavType
import androidx.navigation.compose.NavHost
import androidx.navigation.compose.composable
import androidx.navigation.navArgument
import io.nst.cj.presentation.about.AboutScreen
import io.nst.cj.presentation.jobdetails.JobDetailsScreen
import io.nst.cj.presentation.jobopenings.JobOpeningsScreen
import io.nst.cj.presentation.jobopenings.JobOpeningsViewModel
import io.nst.cj.presentation.profile.ProfileScreen

@Composable
@ExperimentalFoundationApi
@ExperimentalMaterialApi
fun Navigation(navController: NavHostController) {
    NavHost(navController = navController, startDestination = NavigationItem.JobOpenings.route) {
        composable(route = NavigationItem.JobOpenings.route) {
            val viewModel = hiltViewModel<JobOpeningsViewModel>()
            JobOpeningsScreen(viewModel, navController)
        }

        composable(route = NavigationItem.Profile.route) {
            ProfileScreen()
        }

        composable(route = NavigationItem.About.route) {
            AboutScreen()
        }

        composable(
            route = NavigationItem.JobDetails.route,
            arguments = listOf(
                navArgument("jobId") {
                    type = NavType.StringType
                }
            )
        ) {
            val jobId = it.arguments?.getString("jobId")

            if (jobId != null) {
                JobDetailsScreen(jobId = jobId)
            }
        }
    }
}
R0ck
  • 409
  • 1
  • 15
  • Please provide a minified reproducible example that can be run in isolation. The given code has `BottomSheetBackHandler`, a lot of Dimens, `ScreenHeader`, etc. With this, I can not run the app to debug the issue. – Abhimanyu Aug 18 '22 at 15:42
  • Hi @Abhimanyu ! You are right, I'm sorry. I updated the code. You should be able to look at that now. – R0ck Aug 18 '22 at 15:57
  • Did a new update fixing another things that I forgot @Abhimanyu – R0ck Aug 18 '22 at 16:03
  • Please add code for `HeightSpacer`, `toggleModalBottomSheetState` and `LightBlueBorderTextField` as well. – Abhimanyu Aug 18 '22 at 16:24
  • @Abhimanyu Done, forgot that ones. – R0ck Aug 18 '22 at 16:28

1 Answers1

0

I was able to solve this problem based on this answerhttps://stackoverflow.com/a/72051005/18215416 . I opted for the way of hiding the BottomNavigationView.

R0ck
  • 409
  • 1
  • 15