在Android应用中使用RxJava和MVP

5
我将尝试使用MVP架构并在View端使用RxJava和RxBinding来实现Android应用程序中的屏幕。基本上,我有两个下拉列表、一个文本编辑框和一个默认情况下禁用的按钮。当下拉列表选择了项目且文本字段不为空时,我想启用该按钮。以下是代码:
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 模式中。理想情况下,“启用按钮”的“业务逻辑”应该在 presenter 中。实现这一点的最佳方法是什么?我正在考虑以某种方式将原始观察者传递给 presenter(附带问题是如何传递?),presenter 将组合这些观察者并具有启用按钮的逻辑,最后它只需调用 View 来修改按钮状态即可。
还有更好的选择吗?有没有关于 RxJava 在 View 端使用 MVP 的好例子呢?
2个回答

5

我的建议:

你走在正确的道路上。然而,RxBinding的逻辑仍应保留在视图中。我会把决定是否启用按钮的逻辑移动到Presenter中。

定义一个模型,保存你想要检查的所有字段的值:

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传递给Presenter:

mPresenter.observeChoosableFieldChanges(observable).

在Presenter内部完成其余操作:

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

这非常类似于我建议和实施的方法。唯一的区别是我将3个单独的观察者传递给主持人,而不是在视图端将它们组合起来。将它们组合起来也属于“业务”逻辑。将来我们可能只想使用2个字段,或添加更多字段。 - Anton Tananaev

0

您可以枚举您的资源并将Pair值事件传递给Subject/Processor,在那里您可以进行逻辑判断,是否启用按钮并发布布尔事件。更新Presenter中按钮的人将订阅此Subject/Processor。

这样,您就可以在不更改Presenter-View合同的情况下灵活更改资源和逻辑。

实质上,您可以在Presenter中拥有2个完全解耦的组件:

1)监听传入的视图事件并生成启用或禁用按钮的操作流的组件 2)监听启用/禁用操作并相应地更新视图的组件(您也可以使用Google的Binding Library实现此目的)

这样,您可以启用多个解耦的交互链,同时由于组件的简单性和流连接的清晰性而易于维护。

您还可以使用类似RHub库的东西。您可以在这里找到组件示例。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接