2

I am trying to achieve search functionality in compose using DropDownItem but it is displaying below OutlineTextField. All the available option is not displaying over the content like DropDown menu.

Effort 1: Tried using DropDownMenu but in that case, the text field was not in the correct location and bounced over the screen depending on the list of options. (Working as a popUp)

Effort 2: I can not use ExposedDropDownMenuBox as it will require M3 and I am currently using M2 in my project and we can not convert the whole project to M3 for this.

Any suggestions or solutions would be greatly appreciated.

Here is my SearchField composable look like

    @Composable
fun SearchField(
    optionList: List<Address>,
    label: String,
    searchText: String,
    isSearching: Boolean,
    onValueChange: (String) -> Unit,
) {
    var expanded by remember { mutableStateOf(true) }

    var textfieldSize by remember { mutableStateOf(Size.Zero) }

    var selectedText by remember { mutableStateOf("") }

    val focusRequester = FocusRequester()

//    DropdownMenu(
//        modifier = Modifier
//            .fillMaxWidth()
//            .onGloballyPositioned { coordinates ->
//                //This value is used to assign to the DropDown the same width
//                textfieldSize = coordinates.size.toSize()
//            },
//        expanded = true,
////            properties = PopupProperties(usePlatformDefaultWidth = true),
//        onDismissRequest = {
//        }
//    ) {

        OutlinedTextField(
            value = searchText,
            enabled = true,
            onValueChange = {
                selectedText = it
                onValueChange(it)
            },

            modifier = Modifier
                .fillMaxWidth()
                .onGloballyPositioned { coordinates ->
                    //This value is used to assign to the DropDown the same width
                    textfieldSize = coordinates.size.toSize()
                },
            label = { Text(label) },
        )

        if (expanded) {
            if (isSearching) {
                CircularProgressIndicator()
            }

            optionList.forEach { address ->
                DropdownMenuItem(
                    onClick = {
                        println("Selected Address : ${address.addressLine1}")
                        selectedText = address.addressLine1
                        expanded = !expanded
                    }
                ) {
                    Text(text = address.addressLine1)
                }
            }
        }

//    }

}

Here's what it look like right now

enter image description here

Here is the try with Box

        Box {
        // Address 1
        EditableRow(
//            modifier = Modifier.focusRequester(focusRequester),
            value = state.address1.value.toString(),
            onValueChange = {
                state.address1.value = it
                isSearchExpanded = true
                customerDetailsViewModel.onSearchText(it)
            },
            error = state.address1.error.orEmpty(),
            hintText = stringResource(id = R.string.address),
            enabled = state.isAddressEditable,
            trailingIcon = {
                if (isTrailingVisible.value && state.isAddressEditable) {
                    CloseIcon(modifier = Modifier.clickable { isSearchExpanded = !isSearchExpanded }) {
                        state.address1.value = ""
                        focusRequester.requestFocus()
                    }
                }
            },
            keyboardOptions = KeyboardOptions.Default.copy(
                imeAction = ImeAction.Done,
            ),
            keyboardActions = KeyboardActions(onDone = {
                focusManager.clearFocus()
            })
        )

        DropdownMenu(modifier = Modifier
            .fillMaxWidth(),
            expanded = isSearchExpanded, onDismissRequest = { }) {

            searchList.forEach { address ->
                DropdownMenuItem(
                    onClick = {
                        state.address1.value = address.addressLine1
//                        selectedText = address.addressLine1
                        isSearchExpanded = !isSearchExpanded
                        focusManager.clearFocus()
                    }
                ) {
                    Text(text = address.addressLine1)
                }
            }
        }

    }
Arpit Patel
  • 7,212
  • 5
  • 56
  • 67

1 Answers1

1

The ExposedDropDownMenuBox exists also for M2 and it is the best option.

In your solution you have to add the DropdownMenu if you want to display the menu in a separate window, on top of other content.

Something like:

    Box() {
        OutlinedTextField(
           //...
        )


        DropdownMenu(
            //...
        ) {

            items.forEach { label ->
                DropdownMenuItem(
                   //....
                )
            }
        }
    }
Gabriele Mariotti
  • 320,139
  • 94
  • 887
  • 841
  • Thank you for response. @Gabriele I am using compose version 1.0.0 and I believe it doesn’t exist in that version. I will try your solution and let you know. I have tried using DropDownMenu but I haven’t tried with Box layout. Second I tried adding DropDownMenu but my co – Arpit Patel Mar 13 '23 at 02:34
  • 1
    @ArpitPatel it would be better to update from 1.0.0 the 1.3.0. The 1.0.0 is very old. – Gabriele Mariotti Mar 13 '23 at 07:48
  • Tried using this way but can not able to trigger click on OutlineTextField. Any suggestion? – Arpit Patel Mar 13 '23 at 14:46
  • True soon will need that updated version of compose but for time being I need to continue using 1.0.0. Tried using `Box` but when i type something in OutlineTextField It is moving focus to DropDownMenu and after that I can not type to OutlineTextField until I select item from DropDown. Any suggestion? – Arpit Patel Mar 13 '23 at 14:58
  • @ArpitPatel You can add a clickable Icon in the trailingIcon attribute : `trailingIcon = { Icon(icon,"contentDescription", modifier = Modifier.clickable { expanded = !expanded }) }` – Gabriele Mariotti Mar 13 '23 at 15:08
  • Check also https://stackoverflow.com/questions/67111020/exposed-drop-down-menu-for-jetpack-compose/67111599#67111599 – Gabriele Mariotti Mar 13 '23 at 15:09
  • Tried adding clickable param to modifier but getting same behaviour. I have added updated code to question for better understandability. – Arpit Patel Mar 13 '23 at 16:05