2

I have some code that utilizes the Material Dialogs library; I have a dialog with four EditText fields (email, name, username, password). I want it so that the dialog's Register button is disabled unless all fields have at least one character in them.

I searched around, and found a way to do this; unfortunately, it doesn't appear to work. For example, if I pull up the dialog and type anything into any single field, the button becomes enabled. However, if I edit a single field and then edit another field but then delete the text inside one of those fields--the button becomes disabled; the same thing happens if I were to fill out all of the fields, then delete the text inside a single field.

I had thought of utilizing another of the suggestions (which would involve writing my own private inner class)--but I didn't think that would matter considering I'd achieve the same thing (at least, to my knowledge).

        //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
Nxt3
  • 1,970
  • 4
  • 30
  • 52

4 Answers4

5

Change your code as :

First of all you need to add textwatcher to particular EditText, which you didn't. Try as below :

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
        }
    });

And then,

@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);
     }
}
Nxt3
  • 1,970
  • 4
  • 30
  • 52
user5716019
  • 598
  • 4
  • 17
  • That doesn't work. No matter how much I type in, the button remains disabled. – Nxt3 Feb 11 '16 at 05:32
  • Check my edited answer or create a class as Shree Krishna suggested in his answer. – user5716019 Feb 11 '16 at 05:38
  • I already tried my own class--and that yielded the same results. – Nxt3 Feb 11 '16 at 05:40
  • Your edit works if I add an `else` statement to account for a user deleting text from the field after all of the fields have been filled out. Thank you! – Nxt3 Feb 11 '16 at 05:51
0

You can do something like this, But don't copy I didn't check the code.

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 }

Use this class

editText.addTextChangedListener(new MyTextWatcher(editText, editText2, myView));
Shree Krishna
  • 8,474
  • 6
  • 40
  • 68
  • 1
    But how is this different than what I'm doing? All I'm doing is creating a class that does the same thing. – Nxt3 Feb 11 '16 at 05:33
  • I tried writing my own class to handle it and the same exact thing happens. I didn't think it would work, consider what I said in the above comment. – Nxt3 Feb 11 '16 at 05:40
  • What you can do is, pass each of the fields in constructor and check if all the editText is empty or not in the `onTextChanged` method. If not then enable your button. – Shree Krishna Feb 11 '16 at 05:43
0

Making minor change in your implementation you could have achieved that. Instead of adding logic to onTextChanged you could have created one method like

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);
    }

and called this method in 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();
                }
            };

Benefit of checking one by one is for example for your email input you want to put extra check then you could add like

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;
}
Rajen Raiyarela
  • 5,526
  • 4
  • 21
  • 41
0

If you want to use single TextWatcher class for multiple edit-texts, this will works only afterTextChanged(Editable editable)

public void afterTextChanged(Editable editable) {
        if (editable == editText1.getEditableText()) {
            // do something
        } else if (editable == editText2.getEditableText()) {
            // do something
        }
    }
Sirisha
  • 423
  • 4
  • 12