EditText addTextChangedListener only for user input
Asked Answered
A

1

7

I have an EditText where I listen for changes in text:

editText.addTextChangedListener(new TextWatcher() {
        @Override
        public void beforeTextChanged(CharSequence s, int start, int count, int after) {}

        @Override
        public void onTextChanged(CharSequence s, int start, int before, int count) {}

        @Override
        public void afterTextChanged(Editable s) {
            // do stuff
        }
    });

This works fine so far, if I type something in the EditText, things in afterTextChanged() are executed. Now, in the same activity I have a ToggleButton which can change the string in the EditText. How do I prevent this text change due to the ToggleButton to trigger "afterTextChanged"?

PS: Not sure whether this is relevant, but specifically I have an EditText which accepts decimal or fractional numbers (e.g. "0.75" or "3/4") and the toggle button should toggle between fractional and decimal display, but should not trigger anything in "afterTextChanged" since the value stays the same (3/4=0.75).

Acnode answered 21/10, 2015 at 11:17 Comment(1)
as simple maintain one flagMaidel
B
11

In my opinion there are two possibilities:

  1. Register / Unregister listener
  2. Flag

Flag example:

public class MainActivity extends AppCompatActivity{
    boolean automaticChanged = false;
    ToggleButton toggleButton;
    EditText editText;
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);

            //...
            toggleButton.setOnClickListener(onClickListener);
            editText.addTextChangedListener(textWatcher);
            //...
        }

        TextWatcher textWatcher = new TextWatcher() {
            @Override
            public void beforeTextChanged(CharSequence s, int start, int count, int after) {
            }

            @Override
            public void onTextChanged(CharSequence s, int start, int before, int count) {
            }

            @Override
            public void afterTextChanged(Editable s) {
                if (!automaticChanged) {
                    // do stuff
                } else {
                    automaticChanged = false;
                }
            }
        };

        View.OnClickListener onClickListener = new View.OnClickListener() {
            @Override
            public void onClick(View v)
            {
                automaticChanged = true;
                // do stuff
            }
        };
    }
}
Bowser answered 21/10, 2015 at 11:23 Comment(3)
Thanks. Works like a charm. Because of "cannot assign a value to a final variable" and "variable is accessed from inner class, needs to be declared final" I acturally used final boolean[] automaticChanged = {false}; and then assign values to automaticChanged[0]Acnode
@Acnode I changed my code, to help you avoid your problem with variable access.Gladstone
It seems like the logical solution but can create issues due to the random execution order of listeners. Might anyone have a better implementation that avoids these problems?Remains

© 2022 - 2024 — McMap. All rights reserved.