2017-06-23 10 views
1

私はMVPデザインパターンを実装しています。私の発表者はビューから新しい値を受け取ります。ビュー上で値が更新されたときにすべてが有効かどうかを自動的にチェックして、次のボタンの状態を管理したい。manage RxJava2でnull boolean PublishSubject

私のフォームには、ユーザーが正しいオプションを選択した場合にのみ表示されるオプションの部分があります。 このオプションの部分には私はバイナリの質問があります。パーツが表示されない場合は、プレゼンター側で質問の値をnullに設定する必要があります。 たとえば、ユーザーがオプションを選択すると、オプションの部分が表示されます。ユーザーが回答を選択します。ユーザーがオプションを変更すると、オプションの部分が非表示になります。その場合、ユーザがオプションの部分を再度表示した場合、回答が選択されていないために、オプションの質問に対する回答をnullに設定する必要があります。

これを行うには、true/falseではなくnull値で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; 
} 

RxJava 2、null値はonNext()方法で許可されていないので問題がある:ここ

コードです。 それで、私はそれをどうやって管理するのですか?

+0

「ブール」の代わりに3状態の列挙型を使用できます。 – akarnokd

+0

これはもっともクリーンな解決策かもしれませんが、ブール値が実際には3つの状態(true、false、null)であることを避けたかったのです。 – Eselfar

答えて

1

null値を送信できるようにするには、ラッパーを使用できます。この構成では、ラッパーを送信します。ラッパーは、値自体がnullであってもnullではありません。

public class BooleanWrapper { 

    public final Boolean value; 

    public BooleanWrapper(Boolean value) { 
     this.value = value; 
    } 
} 

PublishSubject<Boolean>PublishSubject<BooleanWrapper>なりあなたとあなただけのラッパーとデリファレンス必要なあなたのブールを作成する必要があります。

mObsOptionalAnswer.onNext(new BooleanWrapper(isSomething)); 

mObsOptionalAnswer.map(wrapper -> this.isValid(wrapper.value)) 

あなたがそれを行う必要がある場合コード内で複数回使用する場合は、汎用ラッパーを作成することができます(this tutorial)。

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

あなたはconstanteのブールオブジェクト

public static final Boolean RESET_VALUE = new Boolean(false); 

を使用することができ、あなたはemitこの代わりのnullを放出することができます。レシーバは、このインスタンスに対してチェックし、それに応じて動作する必要があります。例えば。

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

私は動作しますが、Androidスタジオから警告が表示されます: "'不必要なボクシング '新しいブール値(false)' "。 – Eselfar

+0

この方法では動作しません。 :/ – Eselfar

+0

まだオブジェクト参照をチェックしていますか?あなたは 'public static final Boolean RESET_VALUE = Boolean.valueOf(false);'を使用することができます。同じ警告が表示されますが、ユースケースでは新しいインスタンスが必要です。 – Blackbelt

関連する問題