Reputation: 13
I'm trying to implement a searchable dropdown menu in Jetpack Compose, but whenever the dropdown appears, the keyboard loses focus and disappears. How can I modify the code to prevent the keyboard from dismissing when the dropdown expands? Additionally, how can I ensure that the dropdown menu always remains anchored below the button? Here's the relevant part of my code:
@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun SelectBox() {
var expanded by remember { mutableStateOf(false) }
var textInput by remember { mutableStateOf("") } // State to hold user input
var selectedDepartment by remember { mutableStateOf<String?>(null) }
val departments = DepartmentData.departments // Sample department data
val focusRequester = remember { FocusRequester() }
// Filtering departments based on user input
val filteredDepartments = departments.filter {
it.lowercase().contains(textInput.lowercase())
}
Box(modifier = Modifier
.fillMaxWidth()
.clickable { expanded = !expanded }) {
OutlinedTextField(
value = textInput,
onValueChange = {
textInput = it
if (it.isNotEmpty()) expanded = true
},
label = { Text("Department") },
modifier = Modifier
.fillMaxWidth()
.height(58.dp)
.focusRequester(focusRequester),
shape = RoundedCornerShape(8.dp),
singleLine = true,
trailingIcon = {
Icon(
imageVector = if (expanded) Icons.Default.KeyboardArrowUp else Icons.Default.KeyboardArrowDown,
contentDescription = "Dropdown toggle",
modifier = Modifier.clickable {
expanded = !expanded
focusRequester.requestFocus() // Maintain focus
}
)
},
colors = TextFieldDefaults.outlinedTextFieldColors(
focusedBorderColor = Color(0xFF153A99),
focusedLabelColor = Color(0xFF153A99)
)
)
DropdownMenu(
expanded = expanded,
onDismissRequest = {
expanded = false
focusRequester.requestFocus()
},
modifier = Modifier
.fillMaxWidth()
.heightIn(max = 100.dp)
) {
filteredDepartments.forEach { department ->
DropdownMenuItem(
text = { Text(department) },
onClick = {
selectedDepartment = department
textInput = department
expanded = false
focusRequester.requestFocus()
}
)
}
}
}
}
Any suggestions on how to resolve the issue of the keyboard dismissing or how to anchor the dropdown properly would be greatly appreciated. Thank you!
I removed the clickable modifier inside the OutlinedTextField to prevent duplicate click events. I called focusRequester.requestFocus() in the click events for the DropdownMenu and the trailing icon to maintain keyboard focus whether the dropdown is expanded or collapsed.
Upvotes: 1
Views: 242
Reputation: 2214
For the issue of keyboard beign dismissed, you can set focusable
property as false in DropdownMenu
. And in terms of anchoring dropdown below textfield, the current code will work fine unless you have kept this code inside Surface
.
The below code works fine for me with proper anchor and keyboard case:
Box(modifier = Modifier.fillMaxWidth().clickable { expanded = !expanded }) {
OutlinedTextField(
value = textInput,
onValueChange = {
textInput = it
expanded = true
},
label = { Text("Department") },
modifier =
Modifier.fillMaxWidth().height(58.dp).focusRequester(focusRequester).onFocusChanged {
if (it.hasFocus) {
expanded = true
}
},
shape = RoundedCornerShape(8.dp),
singleLine = true,
trailingIcon = {
Icon(
imageVector =
if (expanded) Icons.Default.KeyboardArrowUp
else Icons.Default.KeyboardArrowDown,
contentDescription = "Dropdown toggle",
modifier =
Modifier.clickable {
expanded = !expanded
focusRequester.requestFocus() // Maintain focus
}
)
},
colors =
TextFieldDefaults.outlinedTextFieldColors(
focusedBorderColor = Color(0xFF153A99),
focusedLabelColor = Color(0xFF153A99)
)
)
DropdownMenu(
expanded = expanded,
onDismissRequest = { expanded = false },
modifier = Modifier.fillMaxWidth(),
properties = PopupProperties(focusable = false),
) {
filteredDepartments.forEach { department ->
DropdownMenuItem(
text = { Text(department) },
onClick = {
selectedDepartment = department
textInput = department
expanded = false
}
)
}
}
}
Upvotes: 0