2016-10-27 2 views
5

Я пытаюсь реализовать экран в Android-приложении с использованием архитектуры MVP и используя RxJava и RxBinding на стороне View.RxJava и MVP в приложении для Android

В основном у меня есть 2 Spinners, 1 TextEdit и кнопка, которая по умолчанию отключена. Я хочу включить кнопку, когда у Spinners есть элементы, и текстовое поле не пустое. Вот код:

Observable.combineLatest(
     RxAdapterView.itemSelections(mFirstSpinner), 
     RxAdapterView.itemSelections(mSecondSpinner), 
     RxTextView.textChanges(mEditText), 
     new Func3<Integer, Integer, CharSequence, Boolean>() { 
      @Override 
      public Boolean call(Integer first, Integer second, CharSequence value) { 
       return !TextUtils.isEmpty(value); 
      } 
     }).subscribe(new Action1<Boolean>() { 
     @Override 
     public void call(Boolean enable) { 
      mButton.setEnabled(enable); 
     } 
    }); 

Вопрос теперь в том, как интегрировать это в шаблон MVP. В идеале «бизнес-логика» включения кнопки должна быть в презентаторе. Каков наилучший способ достичь этого? Я думаю о том, чтобы каким-то образом передать исходных наблюдателей в презентаторе (как вопрос?), А ведущий объединил этих наблюдателей, и у него была бы логика включения кнопки. В конце концов, это просто вызовет View для изменения состояния кнопки.

Есть ли лучшие варианты? Есть ли хорошие примеры MVP с RxJava на стороне View?

ответ

5

Мое предложение:

Вы на правильном пути. Однако логика RxBinding все еще должна быть в представлении. Я бы переместил логику, связанную с тем, чтобы решить, включать ли кнопку или нет в презентаторе.

Определить модель холдинга значение из всех полей, которые вы хотели бы проверить:

private class ViewValuesModel { 
    public Integer adapter1Value; 
    public Integer adapter2Value; 
    public CharSequence textValue; 

    public ViewValuesModel(Integer adapter1Value, Integer adapter2Value, CharSequence textValue) { 
     this.adapter1Value = adapter1Value; 
     this.adapter2Value = adapter2Value; 
     this.textValue = textValue; 
    } 
} 

Внутренний вид создать Observable:

Observable observable = Observable.combineLatest(
     RxAdapterView.itemSelections(mFirstSpinner), 
     RxAdapterView.itemSelections(mSecondSpinner), 
     RxTextView.textChanges(mEditText), 
     new Func3<Integer, Integer, CharSequence, ViewValuesModel>() { 
      @Override 
      public ViewValuesModel call(Integer first, Integer second, CharSequence value) { 
       return new ViewValuesModel(first, second, value); 
      } 
     } 
) 

Затем пройти этот Observable для ведущего:

mPresenter.observeChoosableFieldChanges(observable). 

Внутренний презентатор делает остальные:

observable 
    .map(new Func1<ViewValuesModel, Boolean>() { 
     @Override 
     public Booleancall(ViewValuesModel viewStates) { 
      return !TextUtils.isEmpty(viewStates.textValue); 
     } 
    }) 
    .subscribe(new Action1<Boolean>() { 
     @Override 
     public void call(Boolean enable) { 
      if (enable) { 
       view.enableButton(); 
      } 
     } 
    }); 
+0

Это очень похоже на подход, который я предложил и внедрил. Единственное отличие состоит в том, что я передаю 3 отдельных наблюдателя в презентацию вместо того, чтобы комбинировать их на стороне обзора.Сочетание 3 из них также является своеобразной «бизнес-логикой». В будущем мы можем использовать только 2 поля или добавить еще несколько. –

0

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

Таким образом, у вас есть возможность изменять источники и логику без изменения контракта с презентатором.

По сути вы можете иметь 2 абсолютно развязаны компоненты в Выступающий:

1) компонент, который слушает входящие просмотра событий и производит поток действия, чтобы включить или отключить кнопку 2) компонент, который прослушивает включить/отключить действия и обновить представление соответственно (это также можно получить с помощью Библиотеки привязки Google)

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

Вы также можете использовать smth как RHub library. Вы можете найти примеры компонентов here

Смежные вопросы