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

user1583209
  • 1,637
  • 3
  • 24
  • 42

1 Answers1

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
            }
        };
    }
}
Artur Szymański
  • 1,639
  • 1
  • 19
  • 22
  • 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]` – user1583209 Oct 21 '15 at 12:23
  • @user1583209 I changed my code, to help you avoid your problem with variable access. – Artur Szymański Oct 21 '15 at 12:45
  • 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? – bemeyer Nov 24 '17 at 09:33