1
\$\begingroup\$

I have 5 fields, and a button below:

enter image description here

If field value is correct, then hint color, bottom line color and icon color should change. If all fields are correct, then the button color should change.

I have code that works (included below) but it's large and complex. I think it can be improved.

I initially tried to add a TextChangedListener with same logic on every field, but it was a bad idea (15 overridden methods). So I created my own class which implements TextWatcher:

binding.textAuthorizationEmail.addTextChangedListener(new inputEditTextWatcher());

I need to check state when all field are correct to change button color. So now I have:

  • 5 global boolean values:

    public class RegistrationActivity extends AbstractActivity {
        private ActivityRegistrationBinding binding;
    
        private boolean isEmailCorrect;
        private boolean isPasswordCorrect;
        private boolean isPasswordRepeatCorrect;
        private boolean isNameCorrect;
        private boolean isPhoneCorrect;;
    
  • 5 AppCompactEditFields with my own inputEditTextWatcher:

     binding.textAuthorizationEmail.addTextChangedListener(new inputEditTextWatcher(
                        binding.textAuthorizationEmail,
                        binding.textAuthorizationEmailWrapper,
                        R.drawable.ic_email,
                        R.drawable.ic_email_correct,
                        true,
                        false,
                        false,
                        false,
                        false));
    

    and inputEditTextWatcher:

    private class inputEditTextWatcher implements TextWatcher {
            private AppCompatEditText editText;
            private TextInputLayout editTextLayout;
            private int defaultIcon;
            private int correctIcon;
            private boolean isEmail;
            private boolean isPassword;
            private boolean isPasswordRepeat;
            private boolean isName;
            private boolean isPhone;
    
            inputEditTextWatcher(AppCompatEditText editText, TextInputLayout editTextLayout, int defaultIcon, int correctIcon,
                                 boolean isEmail,
                                 boolean isPassword,
                                 boolean isPasswordRepeat,
                                 boolean isName,
                                 boolean isPhone) {
                this.editText = editText;
                this.editTextLayout = editTextLayout;
                this.defaultIcon = defaultIcon;
                this.correctIcon = correctIcon;
                this.isEmail = isEmail;
                this.isPassword = isPassword;
                this.isPasswordRepeat = isPasswordRepeat;
                this.isName = isName;
                this.isPhone = isPhone;
            }
    
            @Override
            public void beforeTextChanged(CharSequence s, int start, int count, int after) {
                if (isPassword || isPasswordRepeat) {
                    editTextLayout.setPasswordVisibilityToggleTintList(AppCompatResources.getColorStateList(RegistrationActivity.this, R.color.color_grey));
                } else {
                    editText.setCompoundDrawables(null, null, null, null);
                }
            }
    
            @Override
            public void onTextChanged(CharSequence s, int start, int before, int count) {
                if (editText.getText().length() != 0 && (!isEmail || MeteorUtility.isValidEmail(String.valueOf(binding.textAuthorizationEmail.getText())))) {
                    if (isPassword || isPasswordRepeat) {
                        editTextLayout.setPasswordVisibilityToggleTintList(AppCompatResources.getColorStateList(RegistrationActivity.this, R.color.colorPrimary));
                    } else {
                        editText.setCompoundDrawablesWithIntrinsicBounds(0, 0, correctIcon, 0);
                    }
    
                    editText.setSupportBackgroundTintList(ColorStateList.valueOf(Color.parseColor("#FFD000")));
                    editTextLayout.setDefaultHintTextColor(ColorStateList.valueOf(Color.parseColor("#FFD000")));
                    setGlobalFlag(true);
    
                    if (isSendDataButtonActive()) {
                        binding.buttonAuthorizationSend.setBackgroundColor(getColor(R.color.colorPrimary));
                    }
                } else {
                    if (!isPassword) {
                        editText.setCompoundDrawablesWithIntrinsicBounds(0, 0, defaultIcon, 0);
                    }
    
                    editText.setSupportBackgroundTintList(ColorStateList.valueOf(getColor(R.color.disable_buttom)));
                    editTextLayout.setDefaultHintTextColor(ColorStateList.valueOf(Color.GRAY));
    
                    setGlobalFlag(false);
                    binding.buttonAuthorizationSend.setBackgroundColor(getColor(R.color.disable_buttom));
                }
            }
    
            @Override
            public void afterTextChanged(Editable s) {
    
            }
    
            private void setGlobalFlag(boolean flag) {
                if (isEmail) {
                    isEmailCorrect = flag;
                }
                if (isPassword) {
                    isPasswordCorrect = flag;
                }
                if (isPasswordRepeat) {
                    isPasswordRepeatCorrect = flag;
                }
                if (isName) {
                    isNameCorrect = flag;
                }
                if (isPhone) {
                    isPhoneCorrect = flag;
                }
            }
        }
    
        private boolean isSendDataButtonActive() {
            return isEmailCorrect && isPasswordCorrect && isPasswordRepeatCorrect && isNameCorrect && isPhoneCorrect;
        }
    

I need all these boolean values on constructor to define what global values must be changed. And the password field has some special rules.

How can I make it better?


In case it's useful, the XML for these is:

email

<android.support.design.widget.TextInputLayout
                    android:id="@+id/text_authorization_email_wrapper"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:layout_centerHorizontal="true"
                    android:layout_marginTop="@dimen/margin_ultra_big"
                    android:hint="@string/hint_email"
                    android:paddingLeft="@dimen/padding_default"
                    android:paddingRight="@dimen/padding_default"
                    android:theme="@style/TextLabel">

                    <android.support.v7.widget.AppCompatEditText
                        android:id="@+id/text_authorization_email"
                        android:layout_width="match_parent"
                        android:layout_height="wrap_content"
                        android:drawableEnd="@drawable/ic_email"
                        android:gravity="start"
                        android:inputType="textNoSuggestions"
                        android:singleLine="true" />

                </android.support.design.widget.TextInputLayout>

password

<android.support.design.widget.TextInputLayout
                    android:id="@+id/text_authorization_password_wrapper"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:layout_below="@+id/text_authorization_email_wrapper"
                    android:layout_centerHorizontal="true"
                    android:hint="@string/hint_password"
                    android:paddingLeft="@dimen/padding_default"
                    android:paddingRight="@dimen/padding_default"
                    android:theme="@style/TextLabel"
                    app:passwordToggleEnabled="true"
                    app:passwordToggleTint="@color/color_grey">

                    <android.support.v7.widget.AppCompatEditText
                        android:id="@+id/text_authorization_password"
                        android:layout_width="match_parent"
                        android:layout_height="wrap_content"
                        android:gravity="start"
                        android:inputType="textPassword"
                        android:paddingEnd="-10dp" />
                </android.support.design.widget.TextInputLayout>
\$\endgroup\$

Your Answer

By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Browse other questions tagged or ask your own question.