When I create a TextField using a TextFieldValue as it's value, as soon as I type a character it runs in an infinite loop, logging both my debug message before the condition check and 'show(ime(), fromIme=true)' infinitely until stopped.
TextFieldValue code which causes infinite loop:
@Composable
fun TestTextField() {
val TAG = "TestTextField"
var testState by remember { mutableStateOf(TextFieldValue("")) }
TextField(
value = testState,
onValueChange = {
Log.d(TAG, "TestTextField: onValueChange triggered")
if (testState.text != it.text) {
testState = it
Log.i(TAG, "TestTextField: value changed : $it, ${testState.text}")
}
}
)
}
However if I change the TextField to use a String instead the issue disappears, with the expected one log appearing in LogCat.
String code that doesn't cause a loop:
@Composable
fun TestTextField() {
val TAG = "TestTextField"
var testState by remember { mutableStateOf("") }
TextField(
value = testState,
onValueChange = {
Log.d(TAG, "TestTextField: onValueChange triggered")
if (testState != it) {
testState = it
Log.i(TAG, "TestTextField: value changed : $it, ${testState}")
}
}
)
}
I simplified the code as much as possible to minimise edge cases, and checked it wasn't getting recomposed elsewhere. For my use case I can probably get away with using a String instead of TextFieldValue, but wanted to check if I was missing something or if this was a bug.
Any ideas much appreciated!
EDIT: to help reproduce - I'm using Android Studio Ladybug, and testing on the emulator running a Pixel 5 with API 31. I've managed to reproduce the issue in a brand new app using the blank activity project.
EDIT2: Turns out the issue only appears when typing using an external keyboard, and if typing using the emulator keyboard it doesn't appear. I'll try it out on a real device but it looks likely to be an emulator/keyboard issue.
When I create a TextField using a TextFieldValue as it's value, as soon as I type a character it runs in an infinite loop, logging both my debug message before the condition check and 'show(ime(), fromIme=true)' infinitely until stopped.
TextFieldValue code which causes infinite loop:
@Composable
fun TestTextField() {
val TAG = "TestTextField"
var testState by remember { mutableStateOf(TextFieldValue("")) }
TextField(
value = testState,
onValueChange = {
Log.d(TAG, "TestTextField: onValueChange triggered")
if (testState.text != it.text) {
testState = it
Log.i(TAG, "TestTextField: value changed : $it, ${testState.text}")
}
}
)
}
However if I change the TextField to use a String instead the issue disappears, with the expected one log appearing in LogCat.
String code that doesn't cause a loop:
@Composable
fun TestTextField() {
val TAG = "TestTextField"
var testState by remember { mutableStateOf("") }
TextField(
value = testState,
onValueChange = {
Log.d(TAG, "TestTextField: onValueChange triggered")
if (testState != it) {
testState = it
Log.i(TAG, "TestTextField: value changed : $it, ${testState}")
}
}
)
}
I simplified the code as much as possible to minimise edge cases, and checked it wasn't getting recomposed elsewhere. For my use case I can probably get away with using a String instead of TextFieldValue, but wanted to check if I was missing something or if this was a bug.
Any ideas much appreciated!
EDIT: to help reproduce - I'm using Android Studio Ladybug, and testing on the emulator running a Pixel 5 with API 31. I've managed to reproduce the issue in a brand new app using the blank activity project.
EDIT2: Turns out the issue only appears when typing using an external keyboard, and if typing using the emulator keyboard it doesn't appear. I'll try it out on a real device but it looks likely to be an emulator/keyboard issue.
Share Improve this question edited Mar 24 at 17:55 Oscar Nowell asked Mar 24 at 14:35 Oscar NowellOscar Nowell 2912 silver badges5 bronze badges 2- The code you posted looks OK and it works as expected. I cannot reproduce the issue you describe. It's commendable that you try to create a minimal example, but please always make sure it is still reproducible as in "minimal reproducible example". Please edit your question accordingly. – tyg Commented Mar 24 at 15:32
- Interesting - I tried it again in a brand new project and I could reproduce the issue. I'll play around some more tomorrow and see if I can narrow it down, and in the mean time edit my question with more parameters to see if that helps reproduce it for others. – Oscar Nowell Commented Mar 24 at 17:45
1 Answer
Reset to default 0Having tested around this seems to be an issue when using an external keyboard with an Android Studio emulator.
I've managed to reproduce the infinite loop when typing using an external keyboard in both my production app and a brand new app, using the code in the question.
Using the emulator keyboard and using a real device keyboard doesn't cause the infinite loop issue when using a TextFieldValue.
I can only assume this is a bug with the Emulator.