Search code examples
androiduitextfieldandroid-jetpack-composeonfocusandroid-bottomsheetdialog

Open ModalSheetLayout on TextField focus instead of Keyboard


I am working with Jetpack Compose and I have a page with several TextFields, where I want that, in several of them, when I click on the input, instead of appearing the keyboard, a ModalSheetLayout appears with different layouts that I have. Is this possible? I'm still not able to do this, all I can do is simple things when the focus changes. Can anyone help me?


Solution

  • The below sample should give a basic idea of how to do this.

    Code

    @OptIn(ExperimentalMaterialApi::class)
    @Composable
    fun BottomSheetSelectionDemo() {
        val coroutineScope: CoroutineScope = rememberCoroutineScope()
        val modalBottomSheetState: ModalBottomSheetState = rememberModalBottomSheetState(
            initialValue = ModalBottomSheetValue.Hidden,
        )
        val colors = arrayListOf("Red", "Green", "Blue", "White", "Black")
        val (value, setValue) = remember {
            mutableStateOf(colors[0])
        }
        val toggleModalBottomSheetState = {
            coroutineScope.launch {
                if (!modalBottomSheetState.isAnimationRunning) {
                    if (modalBottomSheetState.isVisible) {
                        modalBottomSheetState.hide()
                    } else {
                        modalBottomSheetState.show()
                    }
                }
            }
        }
    
        ModalBottomSheetLayout(
            sheetState = modalBottomSheetState,
            sheetContent = {
                LazyColumn {
                    items(colors) {
                        Text(
                            text = it,
                            modifier = Modifier
                                .fillMaxWidth()
                                .clickable {
                                    setValue(it)
                                    toggleModalBottomSheetState()
                                }
                                .padding(
                                    horizontal = 16.dp,
                                    vertical = 12.dp,
                                ),
                        )
                    }
                }
            },
        ) {
            Box(
                contentAlignment = Alignment.Center,
                modifier = Modifier.fillMaxSize(),
            ) {
                MyReadOnlyTextField(
                    value = value,
                    label = "Select a color",
                    onClick = {
                        toggleModalBottomSheetState()
                    },
                    modifier = Modifier
                        .fillMaxWidth()
                        .padding(
                            horizontal = 16.dp,
                            vertical = 4.dp,
                        ),
                )
            }
        }
    }
    
    @Composable
    fun MyReadOnlyTextField(
        modifier: Modifier = Modifier,
        value: String,
        label: String,
        onClick: () -> Unit,
    ) {
        Box(
            modifier = modifier,
        ) {
            androidx.compose.material3.OutlinedTextField(
                value = value,
                onValueChange = {},
                modifier = Modifier
                    .fillMaxWidth(),
                label = {
                    Text(
                        text = label,
                    )
                },
            )
            Box(
                modifier = Modifier
                    .matchParentSize()
                    .alpha(0f)
                    .clickable(
                        onClick = onClick,
                    ),
            )
        }
    }