Does this look super terrible and not idiomatic co...
# compose
c
Does this look super terrible and not idiomatic compose? All I want to do is create my own composable called
OutlinedTextFieldWithFocusLostError
I have this
Copy code
var focusLostCount by remember { mutableStateOf(0) }
val shouldDisplayError by remember { derivedStateOf { (focusLostCount > 1) } }
OutlinedTextField( modifier = Modifier.fillMaxWidth(1f)
                  .onFocusChanged { focusState -> if (!focusState.isFocused) { focusLostCount++ } },
So basically I just want a quick solution on a user clicking on a text field, and then clicking away onto another text field, hence triggering shouldDisplayError which itself runs some validation to check if the input is empty. Having a counter seems a little fishy though, hence the question.
d
Is the purpose to validate the text once the field has lost focus?
If so, I wouldn't personally base the error state on whether the field is focused or not. Perhaps perform the validation itself on focus changed. Setting an errorState if the validation fails. Clearing the state when a key press is detected.
1
c
This is apparently something iOS has where if you leave the field it can highlight to yell at you saying "This is required" and so I'm trying to duplicate it here.
z
I would probably write the state in terms of validation, so something like:
Copy code
val isValid: Boolean by remember { mutableStateOf(true) }
OutlinedTextField(….onFocusChanged { if(!isFocused) isValid = isTextValid(text) })
Better yet, move that
isValid
state to your view model, give it a
validate()
method, and just call that validate method when focus is lost.
Copy code
class ViewModel {
  var text: String by mutableStateOf("") // or however you store the text
  var isValid: Boolean by mutableStateOf(true)
    private set

  fun validate() {
    isValid = TODO("validation logic")
  }
}

…

OutlinedTextField(….onFocusChanged { if(!isFocused) viewModel.validate() })
c
@Zach Klippenstein (he/him) [MOD] that's what I had originally. But the focusLost is called immediately hence why I had to use a counter for when it was "really" lost.
z
oh, i see
that seems like a bug to me? The initial state isn’t a change. It’s not documented at all either. I’m not sure if it’s intentional and just not documented, but i’d probably file a bug. Probably too late to change the API, but maybe an
emitInitialState
flag could be useful for that modifier.
c
Ooh. Okay. I will file!
Assigned! 🤞
r
I left a note on the bug
c
Thanks. I will take a look during the week.
@Ralston Da Silva that modifier worked like a charm! Thank you so much for the advice!
r
You're welcome!