Gavin

    Gavin

    1 year ago
    I have a question surrounding the
    TextField
    and related components. I couldn't find a way to filter between an onFocus/blur event vs actual typing/keyboard actions. The
    onValueChange
    handler is firing when I click in and out of the TextField and causes some un-wanted side effects. Am I missing something or is there currently a way (or a way around) to only account for keyboard actions and ignore focus/blur actions?
    r

    Ralston Da Silva

    1 year ago
    I'm not sure I understood your question, but it looks like you want to know when the text in the TextField changes. You could add a check in the onValueChange lambda to make sure your code is run only if the value changed.
    @Composable
    fun TextChangedSample(){
        var value = remember { TextFieldValue("Initial Text") }
        TextField(
            value = value,
            onValueChange = {
                if (value.text != it.text) {
                    // Add your logic here. 
                    // This will only run when the value has changed.
                }
                // Don't forget this, this is an important part of 
                // the TextField API. The developer decides if they 
                // want to accept the text that was entered.
                value = it
            }
        )
    }
    Gavin

    Gavin

    1 year ago
    Sorry this might be hard to explain but I'll try my best to describe the issue i'm having: I have a textfield where if the user types a search term and hits enter, it will generate a pill with that search term inside of it. The user can do this multiple times. So if I hit delete when the text field is empty, it should delete the last pill and put the contents of that pill inside of the textfield for editing. The issue im running into here is that I can't discern a backspace key event from compose. So basically i have logic that says when the textfield contents are empty, if the next action event still results in an empty content state then I know a backspace was pressed. However, my issue is that when you click in and out of the textfield, it also fires the onValueChange event even though nothing changed and there was no keyboard event. Usually that event would be handled by an
    onBlur
    or
    onFocus
    handler. There doesn't seem to be one here so Im curious if I just missed something or how I can get around this.
    r

    Ralston Da Silva

    1 year ago
    Thanks for explaining. So it looks like you want to use the backspace key as a way to trigger something. This is not currently supported. You can listen for the hardware backspace key, but not for the soft keyboard backspace. This is also not supported for the non-compose EditText view. Maybe you could use an IME action (Enter Key) instead of backspace. So in your example if you enter text and press enter it will create a new pill, but if the text is empty and you press enter it will populate the textfield with the text from the previous pill.
    Gavin

    Gavin

    1 year ago
    Ahhh ok thank you for the explanation/clarifying! Yeah i was wondering if there would somehow be a way I didnt know about to listen on that backspace key event. Is it intentional that the onValueChanged handler gets fired when the user clicks in and out of the TextField?
    r

    Ralston Da Silva

    1 year ago
    I'm not sure if it is intentional that onValueChanged fires everytime we gain or lose focus. @Siyamed might have thoughts around this. Anyway, Even if onValueChanged does not fire when we gain/lose focus, I don't think that you should use a call to onValueChanged with null value as a proxy for the backspace key, as there might be other cases where onValueChanged is triggered.
    Gavin

    Gavin

    1 year ago
    Oh yeah I was just detecting that if the text field is empty and we get another onValueChange event, and its still empty then most likely it was a backspace event. But yeah i feel like onValueChange shouldn't fire when we gain/lose focus because the value doesnt actually change.