Tomáš
07/02/2021, 5:23 PMonTextChange
and persist both up somewhere in my domain logic where I 1) update the list of suggestions 2) propagate text and selection back into this composable via descriptionWithSelection
parameter. As you can see from the sample code below, I use this descriptionWithSelection
only to populate the initial textFieldValueState
state but I don't know how to update that state later when a new description comes. See code examples in the thread 🧵
Thanks for any help.Tomáš
07/02/2021, 6:53 PM@Composable
fun AutocompleteTextInputEditText(
descriptionWithSelection: TextFieldValue,
onTextChange: (String, TextRange) -> Unit,
) {
val textFieldValueState = remember {
mutableStateOf(TextFieldValue(descriptionWithSelection.text, descriptionWithSelection.selection))
}
BasicTextField(
value = textFieldValueState.value,
onValueChange = { tfv ->
textFieldValueState.value = tfv
onTextChange(tfv.text, tfv.selection)
}
)
}
I couldn't find any good example of this, which is surprising given how common of a use-case this is. All samples are using a closed local loop of TextFieldValue
without any external input.
My first idea was to remove the "local" state from the equation and simply do this:
@Composable
fun AutocompleteTextInputEditText(
descriptionWithSelection: TextFieldValue,
onTextChange: (String, TextRange) -> Unit,
) {
BasicTextField(
value = descriptionWithSelection,
onValueChange = { tfv ->
onTextChange(tfv.text, tfv.selection)
}
)
}
This doesn't work because of two things:
1. There is a third parameter in TextFieldValue called composition
which changes every thus onValueChange
keeps producing values.
This can be solved by persisting composition
as well or there are other hacks such as using the local state and use copy
method to keep the composition
value locally persisted. But even if I solve this problem, there is a second one.
2. It comes from an asynchronous nature of onValueChange
. It can emit an "old" value while a new one is propagated at the same time which triggers the loop again and the old value overrides the new one. (I hope it makes sense)
I guess I could solve this with some upstream flows with debounce or something but that just seems more complicated than it should be.mattinger
07/03/2021, 12:31 AMmattinger
07/03/2021, 4:10 AMmattinger
07/03/2021, 4:11 AMSOFT_INPUT_ADJUST_RESIZE
but it just made it even worse.Tomáš
07/03/2021, 10:39 AM