android addTextChangedListener(TextWatcher) not working for the second time

2.8k views Asked by At

I have 6 edit texts on my screen (used to enter 6 digits) If I enter 1 digit on one EditText field the focus should go onto the next one and so on. If I hit back space on some edit text field the focus should come to the previous edittext field

For this I used the below code

 EditText2.addTextChangedListener(new TextWatcher() {

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

            if (EditText2.getText().toString().length() == 1) {
                EditText3.requestFocus();
            }
            else if (EditText2.getText().toString().length() == 0) {
                EditText1.requestFocus();
            }
        }

        public void beforeTextChanged(CharSequence s, int start, int count, int after) {

        }

        public void afterTextChanged(Editable s) {

        }
    });

Normally , the ontextchange listener works if I don't hit a backspace on any of the edit texts. If I hit backspace on EditText2 and land on EditText1(some value on it is present) and try to enter something on it. The cursor is not going to EditText2 as addTextChangedListener not working.

Any help is greatly appreciated.

1

There are 1 answers

2
Victor Rendina On

I'm assuming that you've probably set your EditText fields up with a maxLength of 1. Something like this:

<EditText
    android:id="@+id/edit_text_one"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:maxLength="1"
    android:inputType="number"
    android:digits="0123456789"
    />

When your maxLength is set to 1, the TextWatcher will not be triggered when trying to enter additional characters. One way to solve your problem is when moving backwards to use editText.setSelection(0, editText.length()); See below for a working example:

final List<EditText> fields = new ArrayList<>();

fields.add((EditText) findViewById(R.id.edit_text_one));
fields.add((EditText) findViewById(R.id.edit_text_two));
fields.add((EditText) findViewById(R.id.edit_text_three));
fields.add((EditText) findViewById(R.id.edit_text_four));
fields.add((EditText) findViewById(R.id.edit_text_five));
fields.add((EditText) findViewById(R.id.edit_text_six));

for (EditText editText : fields) {
  editText.addTextChangedListener(new TextWatcher() {
    @Override
    public void beforeTextChanged(CharSequence charSequence, int start, int count, int after) {}

    @Override
    public void onTextChanged(CharSequence charSequence, int start, int count, int after) {
      for (int i = 0; i < fields.size(); i++) {
        // Determine which one of the fields is focused
        if (fields.get(i).hasFocus()) {
          if (charSequence.length() == 1) {
            // If the focused field has a character in it, move to the next field
            if (fields.size() > i + 1) {
              EditText nextField = fields.get(i + 1);
              nextField.requestFocus();
            }
          } else if (charSequence.length() == 0) {
            // If the focused field was deleted, move to the previous field
            if (i - 1 >= 0) {
              EditText prevField = fields.get(i - 1);
              prevField.requestFocus();
              // Select the text so it will be replaced when pressing another button
              prevField.setSelection(0, prevField.getText().length());
            }
          }
          break;
        }
      }
    }

    @Override public void afterTextChanged(Editable editable) {}
  });
}