TextWatcher для нескольких полей EditText

У меня есть код, который использует библиотеку диалогов материалов; У меня есть диалог с четырьмя полями EditText (электронная почта, имя, имя пользователя, пароль). Я хочу, чтобы кнопка Регистрация в диалоговом окне была отключена, если только во всех полях нет хотя бы одного символа.

Я искал вокруг и нашел способ сделать это; к сожалению, это не работает. Например, если я открываю диалоговое окно и ввожу что-либо в любое отдельное поле, кнопка становится доступной. Однако, если я редактирую одно поле, а затем редактирую другое поле, но затем удаляю текст внутри одного из этих полей, кнопка становится неактивной; то же самое произойдет, если я заполню все поля, а затем удалю текст внутри одного поля.

Я думал об использовании другого предложения (которое включало бы написание моего собственного частного внутреннего класса), но я не думал, что это будет иметь значение, учитывая, что я достиг того же (по крайней мере, насколько мне известно).

        //registerDialog is a MaterialDialog object
        final View registerAction = registerDialog.getActionButton(DialogAction.POSITIVE);
        final EditText registerNameInput;
        final EditText registerEmailInput;
        final EditText registerUsernameInput;
        final EditText registerPasswordInput;
        if (registerDialog.getCustomView() != null) {
            registerNameInput = (EditText) registerDialog.getCustomView().findViewById(R.id.register_name);
            registerEmailInput = (EditText) registerDialog.getCustomView().findViewById(R.id.register_email);
            registerUsernameInput = (EditText) registerDialog.getCustomView().findViewById(R.id.register_username);
            registerPasswordInput = (EditText) registerDialog.getCustomView().findViewById(R.id.register_password);

            /*
             * TextWatcher lets us monitor the input fields while registering;
             * This make sure we don't allow the user to register with empty fields
             */
            TextWatcher watcher = 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) {
                    registerAction.setEnabled(s.toString().trim().length() > 0);
                }
                @Override
                public void afterTextChanged(Editable s) {
                }
            };
            /*We want to watch all EditText fields for input*/
            registerNameInput.addTextChangedListener(watcher);
            registerEmailInput.addTextChangedListener(watcher);
            registerUsernameInput.addTextChangedListener(watcher);
            registerPasswordInput.addTextChangedListener(watcher);
        }
    registerDialog.show();
    registerAction.setEnabled(false); //disabled by default

person Nxt3    schedule 11.02.2016    source источник
comment
Вы говорите, что хотите добавить один и тот же TextWatcher в несколько editText?   -  person Shree Krishna    schedule 11.02.2016
comment
@ShreeKrishna Да; согласно другим ответам на SO - способ, которым я это реализовал, должен был быть способом сделать это.   -  person Nxt3    schedule 11.02.2016


Ответы (4)


Измените свой код как:

Прежде всего, вам нужно добавить textwatcher в конкретный EditText, чего вы не сделали. Попробуйте, как показано ниже:

yourEditText.addTextChangedListener(new TextWatcher() {
        @Override
        public void onTextChanged(CharSequence s, int start, int before, int count) {

            // TODO Auto-generated method stub
        }

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

            // TODO Auto-generated method stub
        }

        @Override
        public void afterTextChanged(Editable s) {

            // TODO Auto-generated method stub
        }
    });

А потом,

@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
     if (registerNameInput.getText().toString().length() > 0
                && registerEmailInput.getText().toString().length() > 0
                && registerUsernameInput.getText().toString().length() > 0
                && registerPasswordInput.getText().toString().length() > 0) {
                    registerAction.setEnabled(true);
     } else {
         registerAction.setEnabled(false);
     }
}
person user5716019    schedule 11.02.2016
comment
Это не работает. Независимо от того, сколько я печатаю, кнопка остается неактивной. - person Nxt3; 11.02.2016
comment
Проверьте мой отредактированный ответ или создайте класс, как предложил Шри Кришна в своем ответе. - person user5716019; 11.02.2016
comment
Я уже пробовал свой собственный класс - и это дало те же результаты. - person Nxt3; 11.02.2016
comment
Ваше редактирование работает, если я добавлю оператор else для учета пользователя, удаляющего текст из поля после того, как все поля были заполнены. Спасибо! - person Nxt3; 11.02.2016

Вы можете сделать что-то подобное, но не копируйте, я не проверял код.

public class MyTextWatcher implements TextWatcher {

    EditText editText, anotherEditText;
    View myView;

// Your constructor
    public MyTextWatcher(EditText editText, EditText anotherEditText View myView) {
        this.editText = editText;
        this.myView = myView
        this.anotherEditText = anotherEditText
    }
 @Override
   public void beforeTextChanged(CharSequence s, int start, int count, int after) {
      }

 @Override
   public void onTextChanged(CharSequence s, int start, int before, int count) { 
      if(anotherEditText.getText().toString().trim().lenght()>0){
           myView.setEnabled(s.toString().trim().length() > 0);
        }
   }

 @Override
   public void afterTextChanged(Editable s) {//something }

Использовать этот курс

editText.addTextChangedListener(new MyTextWatcher(editText, editText2, myView));
person Shree Krishna    schedule 11.02.2016
comment
Но чем это отличается от того, что я делаю? Все, что я делаю, это создаю класс, который делает то же самое. - person Nxt3; 11.02.2016
comment
Я попытался написать свой собственный класс, чтобы справиться с этим, и происходит то же самое. Я не думал, что это сработает, подумайте о том, что я сказал в комментарии выше. - person Nxt3; 11.02.2016
comment
Что вы можете сделать, так это передать каждое из полей в конструктор и проверить, является ли весь editText пустым или нет в методе onTextChanged. Если нет, то включите свою кнопку. - person Shree Krishna; 11.02.2016

Внеся незначительные изменения в свою реализацию, вы могли бы этого добиться. Вместо добавления логики в onTextChanged вы могли бы создать один метод, например

private void validateInput(){
        boolean enableButton = true;
        if (registerNameInput.getText() == null || registerNameInput.getText().toString() == null || registerNameInput.getText().toString().trim().length() == 0){
            enableButton = false;
        }
        if (registerEmailInput.getText() == null || registerEmailInput.getText().toString() == null || registerEmailInput.getText().toString().trim().length() == 0){
            enableButton = false;
        }
if (registerUsernameInput.getText() == null || registerUsernameInput.getText().toString() == null || registerUsernameInput.getText().toString().trim().length() == 0){
            enableButton = false;
        }
if (registerPasswordInput.getText() == null || registerPasswordInput.getText().toString() == null || registerPasswordInput.getText().toString().trim().length() == 0){
            enableButton = false;
        }


        registerAction.setEnabled(enableButton);
    }

и вызвал этот метод в afterTextChanged()

TextWatcher watcher = 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) {
                    validateInput();
                }
            };

Преимущество проверки по одному, например, для вашего ввода электронной почты, вы хотите поставить дополнительную проверку, тогда вы можете добавить, как

if (registerEmailInput.getText() == null || registerEmailInput.getText().toString() == null || registerEmailInput.getText().toString().trim().length() == 0){
                enableButton = false;
            }else{
            //put if block to check email input format is correct or not, if not then set enableButton = false;
}
person Rajen Raiyarela    schedule 11.02.2016

Если вы хотите использовать один класс TextWatcher для нескольких текстов редактирования, это будет работать только после того, как TextChanged (редактируемый редактируемый)

public void afterTextChanged(Editable editable) {
        if (editable == editText1.getEditableText()) {
            // do something
        } else if (editable == editText2.getEditableText()) {
            // do something
        }
    }
person Sirisha    schedule 27.09.2017