Android 使用RxJava2 PublishSubject管理空布尔值

Android 使用RxJava2 PublishSubject管理空布尔值,android,mvp,rx-java2,Android,Mvp,Rx Java2,我正在实现MVP设计模式。“我的演示者”从视图接收新值。我想通过在视图上更新值时自动检查所有内容是否有效来管理“下一步”按钮的状态 在我的表单中,我有一个可选部分,仅当用户选择正确的选项时才会显示。 在这个可选部分,我有一个二元问题。如果没有显示零件,我需要在演示者一侧将问题的值设置为null。 例如,用户选择该选项并显示可选零件。用户选择答案。然后用户更改选项,并隐藏可选部分。在这种情况下,我需要将可选问题的答案设置为null,如果用户再次显示可选部分,则答案不会被选中 为此,我使用null值

我正在实现MVP设计模式。“我的演示者”从视图接收新值。我想通过在视图上更新值时自动检查所有内容是否有效来管理“下一步”按钮的状态

在我的表单中,我有一个可选部分,仅当用户选择正确的选项时才会显示。 在这个可选部分,我有一个二元问题。如果没有显示零件,我需要在演示者一侧将问题的值设置为null。 例如,用户选择该选项并显示可选零件。用户选择答案。然后用户更改选项,并隐藏可选部分。在这种情况下,我需要将可选问题的答案设置为null,如果用户再次显示可选部分,则答案不会被选中

为此,我使用null值而不是true/false来调用Presenter上的方法

代码如下:

private final PublishSubject<Boolean> mObsOptionalAnswer = PublishSubject.create();

public MyPresenter(){
    // Combine all the values together to enable/disable the next button
    Observable.combineLatest(
        // ... other fields
        // I need this to return false if the optional part is 
        // displayed but nothing is selected
        mObsOptionalAnswer.map(this::isValid),
        (...) -> ...
    ).subscrible(enable ->{
        mView.enableBtn(enable);
    });     
}

public void myFunction(Boolean isSomething){
    // ... some code
    mObsOptionalAnswer.onNext(isSomething);
}

private boolean isValid(Boolean value){
    return value != null;
}
private final PublishSubject mObsOptionalAnswer=PublishSubject.create();
公共MyPresenter(){
//将所有值组合在一起以启用/禁用“下一步”按钮
可观察的(
//……其他领域
//如果可选部分为,我需要返回false
//显示但未选择任何内容
mObsOptionalAnswer.map(this::isValid),
(...) -> ...
).subscrible(启用->{
mView.enableBtn(enable);
});     
}
public void myFunction(布尔值isSomething){
//…一些代码
mObsOptionalAnswer.onNext(isSomething);
}
私有布尔值有效(布尔值){
返回值!=null;
}
问题是,由于RxJava 2,
null
值在
onNext()
方法中是不允许的。
那么,我应该如何管理它呢?

您可以使用constante布尔对象

 public static final Boolean RESET_VALUE = new Boolean(false);
您可以发出
emit
此命令,而不是发出
null
。接收者必须对照这个实例进行检查,并做出相应的行为。例如

.subscrible(enable ->{
    if (enable != RESET_VALUE) {
        mView.enableBtn(enable);
    } 
});

如果希望能够发送空值,可以使用包装器。在此配置中,您发送包装器,即使值本身为空,包装器也不是空的

public class BooleanWrapper {

    public final Boolean value;

    public BooleanWrapper(Boolean value) {
        this.value = value;
    }
}
您的
PublishSubject
将成为
PublishSubject
,您只需创建包装器并在需要时取消引用布尔值:

mObsOptionalAnswer.onNext(new BooleanWrapper(isSomething));

如果需要在代码中多次这样做,可以创建一个通用包装器(如所述):

公共类可选{
私人决赛M可选;
公共可选(@Nullable M可选){
this.optional=可选;
}
公共布尔值为空(){
返回this.optional==null;
}
公共M get(){
返回可选;
}
}

您可以使用3状态枚举而不是
布尔值。
也许这是最干净的解决方案,但我想避免这种情况,因为布尔值实际上已经有3个状态(真、假、空)。我可以工作,但我从Android Studio收到警告:“
不必要的装箱”新布尔值(假)
”。您还在检查对象引用吗?顺便说一句,您可以使用公共静态最终布尔重置值=Boolean.valueOf(false)。它会给你同样的警告,但是对于你的用例,你需要一个新的实例。我刚刚更改了
public static final Boolean RESET\u VALUE=Boolean.FALSE的代码如您所建议,但它不起作用。
new Boolean(false)
Boolean.valueOf(false)
之间有什么区别?根据文档,最好使用静态工厂方法<代码>注意:很少使用此构造函数。除非需要新实例,否则静态工厂#valueOf(boolean)通常是更好的选择。它可能会产生显著更好的空间和时间性能。
mObsOptionalAnswer.map(wrapper -> this.isValid(wrapper.value))
public class Optional<M> {

    private final M optional;

    public Optional(@Nullable M optional) {
        this.optional = optional;
    }

    public boolean isEmpty() {
        return this.optional == null;
    }

    public M get() {
        return optional;
    }
}