5

我正在尝试使用 MVP 架构并在视图端使用 RxJava 和 RxBinding 在 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 来修改按钮状态。

有没有更好的选择?在 View 端有没有 RxJava 的 MVP 的好例子?

4

2 回答 2

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();
            } 
        }
    });
于 2016-10-27T07:28:25.320 回答
0

您可以枚举您的源并将 Pair 值事件传递给主题/处理器,您可以在其中执行是否启用按钮和发布布尔事件的逻辑。从演示者更新按钮的人将订阅此主题/处理器。

像这样,您可以灵活地更改源和逻辑,而无需更改 Presenter-View 合约。

本质上,您可以在 Presenter 中拥有 2 个绝对解耦的组件:

1) 侦听传入视图事件并产生动作流以启用或禁用按钮的组件 2) 侦听启用/禁用动作并分别更新视图的组件(您也可以使用 Google 的绑定库来实现)

通过这种方式,您可以启用多个解耦的交互链,并且易于维护应有的组件的琐碎性和流连接的清晰性。

你也可以使用RHub library 之类的东西。您可以在此处找到组件示例

于 2016-10-27T15:41:50.787 回答