I'm making an AutoComplete composeable function based on this answer:
@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun AutoComplete(
labelText: String,
options: List<String>,
value: String,
onValueChange: (String) -> Unit,
modifier: Modifier = Modifier,
keyboardOptions: KeyboardOptions = KeyboardOptions.Default,
) {
var expanded = value.length > 2
val filterOpts = options.filter { it.contains(value, ignoreCase = true) }
ExposedDropdownMenuBox(
expanded = expanded,
onExpandedChange = { expanded = !expanded }) {
TextField(
label = { Text(text = labelText) },
readOnly = true,
value = value,
onValueChange = onValueChange,
colors = ExposedDropdownMenuDefaults.textFieldColors(),
modifier = modifier.menuAnchor(),
keyboardOptions = keyboardOptions,
)
if (!filterOpts.isEmpty()) {
ExposedDropdownMenu(
expanded = expanded,
onDismissRequest = { expanded = false }) {
filterOpts.forEach { option ->
DropdownMenuItem(
text = { Text(text = option) },
onClick = {
onValueChange(option)
expanded = false
}
)
}
}
}
}
}
I'm using it like this:
val names = listOf("Tony Stark", "Steve Rogers", "Bruce Banner", "Natasha Romanoff")
var name by remember {
mutableStateOf("")
}
AutoComplete(
labelText = "Name",
options = names,
value = name,
onValueChange = { name = it },
)
When I run this and focus on the Name field, I don't get an on-screen keyboard in the emulator and typing on my laptop does nothing. What am I missing? How do I focus the child TextField
so that the system automatically shows a keyboard?
If you want a keyboard you shouldn't set readOnly = true
.
Also, I don't know what are you trying to achieve, but var expanded = value.length > 2
will keep dropdown menu open even after an option is selected. To avoid this, you can declare expanded
as a regular remembered boolean:
var expanded by remember { mutableStateOf(false) }
And check value length only after a value change in TextField
:
onValueChange = {
expanded = value.length > 2
onValueChange(it)
},