Search code examples
androidandroid-edittextandroid-textwatcher

Using common generic TextWatcher for whole project


How good is using a common generic textwatcher for whole project in terms of performance and optimization?In my project I am using many editext and each edittext has listener to be implemented. I created a generic text watcher like this.Since in each listener i need to access other views of screen i am passing those views in constructor.While the below approach improves readibility of code it does introduces a casting overhead.Is it good practice to follow this approach?Is there any better approach i can follow?-

public class GenericTextWatcher implements TextWatcher {

    private View view,view2,view3,view4;
    public  GenericTextWatcher(View view) {
        this.view = view;
    }
    public GenericTextWatcher(View view,View view2,View view3) {
         this.view = view;
        this.view2=view2;
        this.view3=view3;
     }
    public GenericTextWatcher(View view,View view2) {
        this.view = view;
        this.view2=view2;
    }
    public GenericTextWatcher(View view,View view2,View view3,View view4) {
        this.view = view;
        this.view2=view2;
        this.view3=view3;
        this.view4=view4;
    }

    public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {}
    public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {
        switch (view.getId())
        {
            case R.id.etMfafasf:
                if (((EditText)view).getText().length()==8 &&((EditText)view2).getText().length()>0)
                    ((TextView)view3).setEnabled(true);
                else
                    ((TextView)view3).setEnabled(false);
                break;
            case R.id.etModaDFFSA:
                if (((EditText)view2).getText().length()>0 &&((EditText)view).getText().length()==8)
                    ((TextView)view3).setEnabled(true);
                else
                    ((TextView)view3).setEnabled(false);
               ValidationUtils.checkfasffsfimit(charSequence,(TextInputLayout)view4);
                break;

            case R.id.etMoXYZ:
                if (((EditText)view).getText().length()==8)
                    ((TextView)view2).setEnabled(true);
                else
                    ((TextView)view2).setEnabled(false);
                break;
        }
    }

    public void afterTextChanged(Editable editable) {

    }
}

Calling TextWatcher

etNumber.addTextChangedListener(new GenericTextWatcher(etNumber,tvNdf));

Solution

  • I suppose you could develop this in a more structured manner if you wish to avoid the type casting cost at the runtime.

    public class GenericTextWatcher implements TextWatcher {
    
        private EditText[] mEditArray;
        private TextView[] mTextArray;
    
        public  GenericTextWatcher(EditText[] editArray, EditText textArray) {
            mEditArray = editArray;
            mTextArray = textArray;
        }
    
        public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {
            switch (view.getId())
            {
                case R.id.etMfafasf:
    
                    EditText view= mEditArray[0], view2 = mEditArray[1];
    
                    TextView view3 = mTextArray[0]; 
                    if (view.getText().length()==8 && view2.getText().length()>0)
                        view3.setEnabled(true);
                    else
                        view3.setEnabled(false);
                    break;
    
                case R.id.etModaDFFSA:
                    EditText view= mEditArray[0], view2 = mEditArray[1];
    
                    TextView view3 = mTextArray[0]; 
                    if (view2.getText().length()>0 && view.getText().length()==8)
                        view3.setEnabled(true);
                    else
                        view3.setEnabled(false);
                   ValidationUtils.checkfasffsfimit(charSequence,(TextInputLayout)view4);
                    break;
    
                case R.id.etMoXYZ:
                    EditText view= mEditArray[0], view2 = mEditArray[1];
    
                    if (view.getText().length()==8)
                        view2.setEnabled(true);
                    else
                        view2.setEnabled(false);
                    break;
            }
        }
     }
    

    And you could call this allocate a listener this way :

    etNumber.addTextChangedListener(
    new GenericTextWatcher(new EditText[]{etNumber}, new TextView[]{tvNdf}));
    

    This will make it cleaner since you are overloading the constructors based on number of arguments... This mayn't be the best design since tomorrow let's say you'll need a constructor with 10 views, your overloaded constructor will grow like GenericTextWatcher(view, view1, view2 ...., view9)