How to prevent initial onFocus trigger on TextField during first composition

Viewed 23

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.

1 Answers

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..

Related