I have a `TextField` with validations, I want to s...
# compose
a
I have a
TextField
with validations, I want to show error(make
isError
property equals to true) only after losing the TextField's focus, not on the initial composition, how I can accomplish that?
z
You can observe focus state changes using the
onFocusChanged
modifier
a
That's right, but I want to show the error only when the user leaves the input(losing input focus) and moves to another input.
onFocusChanged
gives me the current state, so If I depend on
hasFocus = false
it'll show the error each time the field has no focus which isn't intended
z
each time the field has no focus
I don’t understand the difference between those scenarios.
onFocusChanged
gives you a callback when the focus state changes. As far as I can tell what you’re looking for is a signal that the focus state has changed from focused to not focused. Or do you want to get a signal when focus has moved to another text field, but not to potentially something else?
a
Copy code
As far as I can tell what you're looking for is a signal that the focus state has changed from focused to not focused.
Exactly. The difference here is that
onFocusChanged
will produce
hasFocus = false
on the initial composition, therefore, if I depend on this to show the error will show the error on all existing Inputs on the initial composition.
z
So ignore the first callback
a
How I can detect the initial composition?
a
I faced exactly the same issue. This is how I fixed it.
Copy code
@Composable
fun MyCustomTextField() {
    var text by remember {
        mutableStateOf("")
    }

    var shouldShowError by remember {
        mutableStateOf(false)
    }

    var shouldShowErrorFirstTime by remember {
        mutableStateOf(false)
    }


    TextField(value = text, onValueChange = { text = it }, modifier = Modifier.onFocusChanged {

        if (!it.isFocused && shouldShowErrorFirstTime) { // on first onFocusChanged, shouldShowErrorFirstTime is still false so it won't go in if.

            // here validate
            if(text.length < 5){
                shouldShowError = true
                shouldShowErrorFirstTime = false
            }else{
                shouldShowError = false
                shouldShowErrorFirstTime = true
            }

        }else{
            shouldShowErrorFirstTime = true // this will happen on first onFocusChanged callback so error will be hidden.
        }

    }, label = {
        Text(text = "Enter Text")
    })
    Spacer(Modifier.size(16.dp))
    ShowError(visible = shouldShowError && !shouldShowErrorFirstTime)
    Spacer(Modifier.size(16.dp))
    TextField(value = "", onValueChange = {}, label = {
        Text(text = "Click to focus out")
    })
}

@Composable
fun ShowError(visible: Boolean) {
    if(visible){
        Text(text = "Error")
    }
}
it will skip initial composition and no error will be shown. After first focus In and out, error will be shown if these is.
a
Thanks for sharing, I think we have the ability to detect the initial composition but I didn't find the code
271 Views