October 23, 2024
Chicago 12, Melborne City, USA
Android

return focus to OutlinedTextField when showing prediction


I did a simple CustomTextField based on OutlinedTextField and DropDownMenu, to be able to show to user prediction when typing text. There are predictionValues: List<String> which are compared with actual typing and visible when at least first 3 characters match. But after prediction values are showed in DropDownMenu OutlinedTextField losts focus, and I am not able to return it so user can not write further characters. Any idea ho to solve this?

@Composable
fun CustomTextField(
    name: String,
    value: String,
    onChange: (String) -> Unit,
    predictionValues: List<String> = emptyList(),
    visualTransformation: VisualTransformation? = null,
    modifier: Modifier = Modifier, 
    keyboardType: KeyboardType? = null,
    imeAction: ImeAction? = null,
    isEnabled: Boolean = true,
    keyboardActions: KeyboardActions = KeyboardActions.Default,
    trailingIcon: @Composable (() -> Unit)? = null
) {
     var expanded by remember { mutableStateOf(false) }
     var filteredOptions by remember { mutableStateOf<List<String>>(emptyList()) }
     val focusRequester = remember { FocusRequester() }
 
     var textFieldValue by remember { mutableStateOf(TextFieldValue(text = value)) }
 
     fun filterOptions(query: String) {
         if (query.length >= 3) {
             filteredOptions = predictionValues.filter { it.contains(query, ignoreCase = true) }
             expanded = filteredOptions.isNotEmpty()
         } else {
             expanded = false
         }
     }
 
     LaunchedEffect(textFieldValue.text) {
         if (textFieldValue.text != value) {
             onChange(textFieldValue.text)
         }
     }
 
     Column(modifier = modifier.fillMaxWidth()) {
 
         OutlinedTextField(
             value = textFieldValue,
             onValueChange = { newValue ->
                 textFieldValue = newValue
                 filterOptions(newValue.text)
             },
             enabled = isEnabled,
             modifier = Modifier
                 .fillMaxWidth()
                 .focusRequester(focusRequester),
             keyboardOptions = keyboardOptions ?: KeyboardOptions(
                 keyboardType = keyboardType ?: KeyboardType.Text,
                 imeAction = imeAction ?: ImeAction.Default
             ),
             singleLine = true,
             label = { Text(text = name) },
             visualTransformation = visualTransformation ?: VisualTransformation.None,
             keyboardActions = keyboardActions,
             trailingIcon = { trailingIcon?.invoke() }
         )
 
         DropdownMenu(
             expanded = expanded,
             onDismissRequest = { expanded = false }
         ) {
             filteredOptions.forEach { option ->
                 DropdownMenuItem(
                     text = { Text(option) },
                     onClick = {
                         textFieldValue = TextFieldValue(
                             text = option,
                             selection = TextRange(option.length)
                         )
                         expanded = false
                         focusRequester.requestFocus()
                     }
                 )
             }
         }
 
         if (expanded) {
             LaunchedEffect(Unit) {
                 focusRequester.requestFocus()
             }
         }
     }
 }



You need to sign in to view this answers

Leave feedback about this

  • Quality
  • Price
  • Service

PROS

+
Add Field

CONS

+
Add Field
Choose Image
Choose Video