I am creating an sample screen in compose, where i need to show the dropdown with suggesstions while the user is typing without losing the TextField focus.
Desired Output:
When i have used ExposedDropdownMenuBox, dropdown is showing on top of TextField.
@Composable
fun AutoCompleteTextView(
modifier: Modifier = Modifier,
textFieldValue: TextFieldValue = TextFieldValue(),
onTextChanged: ((TextFieldValue) -> Unit) = ::onTextChnaged,
textStyle: TextStyle = TextStyle.Default,
singleLine: Boolean = false
) {
val options = listOf("Option 1", "Option 2", "Option 3", "Option 4", "Option 5")
var isDropdownVisible by remember { mutableStateOf(false) }
var expanded by remember { mutableStateOf(false) }
var selectedOptionText by remember { mutableStateOf("") }
ExposedDropdownMenuBox(
modifier = Modifier,
expanded = expanded,
onExpandedChange = { expanded = it }) {
TextField(
value = textFieldValue,
onValueChange = { value ->
onTextChanged(value)
value.selection.start
isDropdownVisible = value.text.isNotEmpty() && value.text.first() == '@'
},
label = { Text("Enter your text here.") },
trailingIcon = { ExposedDropdownMenuDefaults.TrailingIcon(expanded = expanded) },
textStyle = textStyle,
singleLine = singleLine,
modifier = modifier.menuAnchor(),
)
// filter options based on text field value
val filteringOptions = options.filter { it.contains(selectedOptionText, ignoreCase = true) }
if (filteringOptions.isNotEmpty()) {
ExposedDropdownMenu(
expanded = expanded,
onDismissRequest = { expanded = false },
) {
filteringOptions.forEach { selectionOption ->
DropdownMenuItem(
text = { Text(selectionOption) },
onClick = {
selectedOptionText = selectionOption
expanded = false
},
contentPadding = ExposedDropdownMenuDefaults.ItemContentPadding,
)
}
}
}
}
BackHandler(enabled = isDropdownVisible) {
isDropdownVisible = false
}
}
fun onTextChnaged(textFieldValue: TextFieldValue): Unit {
}
Output image:
In Android Compose, to anchor the
ExposedDropdownMenuto theTextFieldcursor and show suggestions as a user types, you need to adjust the position of yourExposedDropdownMenuso that it appears near the text cursor (caret), and update the filtering logic to respond to text changes. Here's an updated version of yourAutoCompleteTextViewComposable that includes the positioning of the DropdownMenu based on the TextField cursor.Key changes and considerations:
A
modifierhas been applied toTextFieldto calculate the global position of the text field and get the size, which is later used to determine the dropdown position.The
onGloballyPositionedmodifier is used to calculate the cursor position within the TextField.The dropdown menu is positioned using
offsetwhich takescursorPositionto position the dropdown menu relative to the cursor within theTextField.You'll want to make sure that the cursor position is updated every time the text changes in such a way that it might affect the cursor's position on the screen. This includes changes to the
TextFieldValue.This is a basic implementation and could be further refined based on specific UI and UX requirements. For example, handling screen rotations, complex UI layouts, handling keyboard appearance, etc., would require additional work.