Использование общего универсального TextWatcher для всего проекта

Насколько хорошо использование общего универсального текстового наблюдателя для всего проекта с точки зрения производительности и оптимизации? В моем проекте я использую много editext, и каждый edittext имеет слушателя для реализации. Я создал общий наблюдатель текста следующим образом. Так как в каждом слушателе мне нужно получить доступ к другим представлениям экрана, я передаю эти представления в конструкторе. Хотя приведенный ниже подход улучшает читабельность кода, он вносит накладные расходы на приведение. Это хорошая практика, которой нужно следовать этот подход? Есть ли лучший подход, которым я могу следовать?-

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) {

    }
}

Вызов TextWatcher

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

2 ответа

Решение

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

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

И вы могли бы назвать это распределить слушателя следующим образом:

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

Это сделает его чище, так как вы перегружаете конструкторы на основе количества аргументов... Возможно, это не лучший дизайн, поскольку завтра, скажем, вам понадобится конструктор с 10 представлениями, ваш перегруженный конструктор будет расти как GenericTextWatcher(view, view1, view2 ...., view9)

Ваш код будет работать нормально. Но если вы хотите лучшие практики, я предлагаю опубликовать / подписаться.

Например, EventBus из Google Guava Library - "Связь между компонентами в стиле публикации-подписки без необходимости явной регистрации компонентов друг с другом".

Вот пример,

В своей деятельности или фрагменте создайте шину событий

EventBus eventBus = new EventBus();

Зарегистрируйте объекты, которые будут прослушивать (подписываться) на события. В этом случае это будет ваша деятельность или фрагмент

eventBus.register(this);

Затем создайте класс, который будет вашим событием

public class EditEvent {
     private CharSequence charSequence, int i, int i1, int i2, int id; // add getters and setters
     public EditEvent(CharSequence charSequence, int i, int i1, int i2, int id)
     {//...}
}

Затем подпишитесь на событие в вашей активности или фрагменте, используя аннотацию @Subscribe

@Subscribe // this will be called when an EditEvent is posted to the bus
public void handleTextChange(EditEvent event) {
     switch (event.id)
     {
           //...
     }
}

Наконец, в наблюдателе каждого просмотра, опубликуйте событие

onTextChanged(CharSequence s, int start, int before, int count)
{
       eventBus.post(new EditEvent(s, start, before, count, EditText.this));
}
Другие вопросы по тегам