Environment
I'm using io.github.dokar3:chiptextfield-m3 on version 0.7.0-alpha05. I discovered this issue using Interactive Mode Preview in Android Studio Meerkat | 2024.3.1 Patch 1 (Build #AI-243.24978.46.2431.13208083), but I suspect it would manifest in an actual device as well.
Issue
When the Input component loses focus, textFieldFocusState does not update. This can cause an issue where state.focusTextField() becomes a no-op and does not move focus to the text field as expected.
Reproduction
- Add a chip to the input field
- Invoke
state.focusTextField() to set state.textFieldFocusState to TextFieldFocusState.Focused
- Move focus to a different component
- Invoke
state.focusTextField() again. Since state.textFieldFocusState is already TextFieldFocusState.Focused, the snapshotFlow that uses it will not emit another value.
- Trying to type into the input field will no longer work. Instead, the first chip is focused.
Proposed solutions
Would it be feasible to either
- update
textFieldFocusState whenever the focus changes, or
- change the way
textFieldFocusState is consumed so that duplicate values are still emitted?
I'm fairly new to Android development, so there might be a better fix.
Code to reproduce
I ran into this issue when building an autocomplete menu that uses ChipTextField. Below is a simplified version. I can share the full code if necessary.
@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun ChipAutocompleteInputField() {
val state = rememberChipTextFieldState<Chip>()
var value by remember { mutableStateOf("") }
var expanded by remember { mutableStateOf(false) }
val options = listOf("first", "second", "third")
Button(onClick = { state.focusTextField() }) {
Text("Invoke focusTextField")
}
ExposedDropdownMenuBox(expanded = expanded, onExpandedChange = { expanded = it }) {
ChipTextField(
state = state,
value = value,
onValueChange = { value = it },
onSubmit = ::Chip,
label = { Text("example") },
innerModifier = Modifier.menuAnchor(MenuAnchorType.PrimaryEditable),
)
ExposedDropdownMenu(expanded = expanded, onDismissRequest = { expanded = false }) {
options.forEach { option ->
DropdownMenuItem(
onClick = {
value = ""
expanded = false
state.addChip(Chip(option))
state.focusTextField()
},
text = { Text(option) },
)
}
}
}
}
@Preview(showBackground = true, widthDp = 300, heightDp = 600)
@Composable
fun ChipAutocompleteInputFieldPreview() {
AppTheme(darkTheme = true) {
Column {
ChipAutocompleteInputField()
}
}
}
Workaround
Changing the Button's onclick to the following fixes the issue.
MainScope().launch {
if (state.isTextFieldFocused) {
state.clearTextFieldFocus()
awaitFrame() // Changes seem to be ignored without this, I guess it only checks once per frame?
}
state.focusTextField()
}
This changes textFieldFocusState so that calling focusTextField will emit a new value, but it's hacky and causes issues if the user is typing quickly.
Environment
I'm using io.github.dokar3:chiptextfield-m3 on version 0.7.0-alpha05. I discovered this issue using Interactive Mode Preview in Android Studio Meerkat | 2024.3.1 Patch 1 (Build #AI-243.24978.46.2431.13208083), but I suspect it would manifest in an actual device as well.
Issue
When the
Inputcomponent loses focus,textFieldFocusStatedoes not update. This can cause an issue wherestate.focusTextField()becomes a no-op and does not move focus to the text field as expected.Reproduction
state.focusTextField()to setstate.textFieldFocusStatetoTextFieldFocusState.Focusedstate.focusTextField()again. Sincestate.textFieldFocusStateis alreadyTextFieldFocusState.Focused, the snapshotFlow that uses it will not emit another value.Proposed solutions
Would it be feasible to either
textFieldFocusStatewhenever the focus changes, ortextFieldFocusStateis consumed so that duplicate values are still emitted?I'm fairly new to Android development, so there might be a better fix.
Code to reproduce
I ran into this issue when building an autocomplete menu that uses
ChipTextField. Below is a simplified version. I can share the full code if necessary.Workaround
Changing the
Button'sonclickto the following fixes the issue.This changes
textFieldFocusStateso that callingfocusTextFieldwill emit a new value, but it's hacky and causes issues if the user is typing quickly.