0

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?

R0ck
  • 409
  • 1
  • 15
  • Why are you using a TextField if you don't want to edit the text? – Gabriele Mariotti Aug 17 '22 at 19:12
  • @GabrieleMariotti it is a good point, indeed. When I did the screen, it was for something like Gmail does with emails (chips) but for tags. Now, what I want is select it from a list in a BottomSheet and present it as a list of chips in a component, so probably I need to change. Any suggestions? – R0ck Aug 17 '22 at 21:23
  • You can also use a TextField with enabled = false – Gabriele Mariotti Aug 18 '22 at 07:29

1 Answers1

1

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,
                ),
        )
    }
}
Abhimanyu
  • 11,351
  • 7
  • 51
  • 121
  • This forces me to put the entire page layout inside the content, right? Given that I have multiple TextFields on this page and I want to open different ModalSheets for all of them, how could I do that? This code helps, but I can't see how I can do this. For example, I click on TextField A and it opens a ModalSheet with a list of fruits, and if I click on B, it opens a ModalSheet with a list of vegetables. This happens on the same page/screen @Abhimanyu – R0ck Aug 17 '22 at 17:08
  • Kindly refer to this repo for that use case as the code would be difficult to add here (a lot of lines) - https://github.com/Abhimanyu14/finance-manager. Module - "feature-transactions". Package - "add_transaction.screen.AddTransactionScreenView" – Abhimanyu Aug 17 '22 at 17:28
  • Also, noticed just now, This logic depends on the click events. If you are looking for a focus change, you can modify it accordingly. – Abhimanyu Aug 17 '22 at 17:33
  • @Abhymanyu I will check it, thanks. Any doubt, I will comment this post again. – R0ck Aug 17 '22 at 21:24
  • @Abhymanyu I managed to implement this, thanks. I have two more questions: the ModalSheet content is being aligned to the left and not to the center, how can I solve this? Modal Sheet is appearing behind BottomNavigation, how can I make it appear in front or hide BottomNavigation? – R0ck Aug 18 '22 at 10:39
  • Hi @R0ck, can you please create new questions and comment on their links here? Answering using the comment would be difficult and a minimum reproducible example helps to answer your question better. – Abhimanyu Aug 18 '22 at 12:14
  • Hi @Abhimanyu ! I'm going to do this after another try which I'm going to do now. If not, I open the question and put the link here. – R0ck Aug 18 '22 at 12:39
  • here is one of my doubts: https://stackoverflow.com/questions/73404439/modalbottomsheetlayout-content-is-not-get-centered-as-well-as-sheet-content – R0ck Aug 18 '22 at 14:03
  • here is the other doubt: https://stackoverflow.com/questions/73405807/modalbottomsheetlayout-is-appearing-behind-bottomnavigation – R0ck Aug 18 '22 at 15:34
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/247370/discussion-between-abhimanyu-and-r0ck). – Abhimanyu Aug 18 '22 at 16:24
  • Sure, send you a message there. – R0ck Aug 18 '22 at 16:29