Reproducible with code:
var value by remember { mutableStateOf("Hello\nWorld\nInvisible") }
TextField(
value = value,
onValueChange = { value = it },
label = { Text("Enter text") },
modifier = Modifier
.onFocusChanged { Log.d("TAG", "1 OnFocusChangedCalled: $it") }
)
TextField(
value = value,
onValueChange = { value = it },
label = { Text("Enter text") },
modifier = Modifier
.onFocusChanged { Log.d("TAG", "2 OnFocusChangedCalled: $it") }
)
Upon simply opening the view, Logcat shows:
D/TAG: 1 OnFocusChangedCalled: Inactive
D/TAG: 2 OnFocusChangedCalled: Inactive
With traditional XML layouts, onFocusChangedListener only triggers when user actually interacts with the field.
With compose layout, I'm trying to do error validation only when user removes focus from a TextField.
However this behaviour is causing my validation to trigger as soon as the view is initialized.
How can I make the onFocusChanged validation only occur after the user removes focus from the field, instead of upon initialization?
You can move the validation in the onValueChange
attribute instead of the onFocusChanged
modifier.
As workaround you can store a key when the a field gains the focus and then check this value when the focus is lost.
Something like:
var focusedTextKey by remember { mutableStateOf("") }
TextField(
value = value,
onValueChange = { value = it },
label = { Text("Enter text") },
modifier = Modifier
.onFocusChanged {
Log.d("TAG", "1 OnFocusChangedCalled: $it")
if (it.isFocused) {
focusedTextKey = "NAME"
} else {
if (focusedTextKey == "NAME") {
//validate the value
}
focusedTextKey = ""
}
}
)