Reputation: 6187
Is there any way I can prevent onFocus
trigger during the initial laying out of a composition?,
.onFocusChanged {
// initial pass triggers un-necessary onFocus callback with just `false` values
Log.e("TextFieldFocusChanged", "${it.isFocused} : ${it.hasFocus}")
}
I have found this Google issue tracker that seems related to such behavior, though the issue is not exactly related to an initial pass of a composition.
This thing can be solved by specifying some boolean
flag depending on your needs, but handling it this way slowly introduces complex boolean
evaluations depending on your use-case. Is there any way I can configure a TextField
to prevent onFocus
callback on initial pass?
Thank you in advance.
Upvotes: 3
Views: 628
Reputation: 235
Indeed you need to manage boolean
flag for this.
Firstly, create a flag state, and set it to true
on first composition:
var isInitialCompositionCompleted by remember { mutableStateOf(false) }
LaunchedEffect(Unit) {
isInitialCompositionCompleted = true
}
Secondly, use regular onFocusChanged
modifier, and simply skip all callbacks until your flag is set to true
:
Modifier.onFocusChanged { focusState ->
if (!isInitialCompositionCompleted) return@onFocusChanged
onFocusChanged(focusState.isFocused)
}
Here onFocusChanged(focusState.isFocused)
is your outer lambda.
Upvotes: 3
Reputation: 6187
There must be a more efficient way to handle this but the most optimal approach I can do for now is to rely on SideEffect
.
@Composable
fun ScreenTextFields() {
//..TextField ... onFocusChanged { onTextFieldFocus(it) }...
//..TextField ... onFocusChanged { onTextFieldFocus(it) }...
//..TextField ... onFocusChanged { onTextFieldFocus(it) }...
//..TextField ... onFocusChanged { onTextFieldFocus(it) }...
SideEffect {
// notify and update a boolean state (e.g onFieldsPostComposition)
}
}
and in a state class.
fun onTextFieldFocus(focusState: FocusState) {
if (onFieldsPostComposition) {
// do intended use-case on actual focus changes
}
}
This way, any initial onFocus
callback can be ignored/skip for your intended logic, the only part I'm not sure if onFocusChanged { ... }
callback is part of the composition/re-composition
, not sure if there's a chance that SideEffect
will occur first before onFocus
callback, but so far, this approach works on my case..
Upvotes: 1