2016-03-04 77 views
1

我想學習一些RxJava和RxAndroid,我認爲我可以輕鬆地用這樣的工具來完成問題。問題如下: 我們可以在活動中使用'N'個視圖,並且每個視圖都用於滿足某些條件。當用戶按下'保存'時,我們要檢查所有視圖中是否滿足所有條件,如果不是,請求用戶分別確認每個視圖。 所以這裏是我將如何處理這個問題沒有RxJava的例子:鏈接在UI線程RxJava調用

private void validation(List<CustomView> views) 
{ 
    for (CustomView view : views) 
    { 
     if (view.metCondition() == false) 
     { 
      showConfirmationDialog(view); 
      return false; 
     } 
    } 

    return true; 
} 


private void showConfirmationDialog(CustomView view) 
{ 
    ConfirmationDialog dialog = new ConfirmationDialog(this, view); 

    dialog.show(); 
} 

private void dialogResult(CustomView view) 
{ 
    view.setCondition(true); 

    validation(mViews); 
} 

很顯然,我想有某種監聽確認結果和條件被確認後的(與確定或取消)「view.metCondition()」將被設置爲true,因此它不會再次彈出該視圖。當然,在「驗證」返回true之後,它會運行「Save()」函數。

這真的很流露我真正的解決方案,因爲我想盡可能保持簡單,所以如果你知道這樣的事情可以做到與RxJava。我已經在使用庫來處理一些異步的東西(與usb連接的設備交談),所以我知道一些東西,但從來不知道如何鏈接這樣的調用。

任何幫助,非常感謝。

編輯

添加偵聽方法,所以我們可以看到「的validate()」功能再次被

回答

3

對於鏈接驗證調用,你應該看看到combineLatest()operator。首先,您每View創建Observable,然後使用該運算符。 RxBinding是Android視圖的優秀擴展。

請參閱this示例。這是一個很好的驗證。

+0

這是我需要的一個很好的例子,但花了我一些時間才真正意識到這一點。非常感謝你。 –

0

只是一個例子靈感:)

private static class CustomViewValidator { 
    //Subject can be attach to other sources eg. EditText etc 
    //Of course it can be replaced with simple variable 
    BehaviorSubject<Boolean> mSubject = BehaviorSubject.create(); 

    Observable<Boolean> getValidationObservable() { 
     return mSubject.asObservable().map(s -> { 
      if (!s) { 
       throw new ViewValidationThrowable(CustomViewValidator.this); 
      } else { 
       return true; 
      } 
     }); 
    } 

    void setCondition(boolean v) { 
     mSubject.onNext(v); 
    } 
} 

private static class ViewValidationThrowable extends RuntimeException { 
    //custom Exception let us to keep reference to invalid View 
    private final CustomViewValidator mView; 

    private ViewValidationThrowable(CustomViewValidator view) { 
     mView = view; 
    } 
} 

private List<CustomViewValidator> mViews; 

private void validate(final List<CustomViewValidator> viewObservables) { 

    Observable.from(viewObservables) 
      .flatMap(CustomViewValidator::getValidationObservable) 
      .subscribe(aBoolean -> { 
         //we can just ignore all items 
        }, 
        throwable -> { 
         if (throwable instanceof ViewValidationThrowable) { 
          CustomViewValidator view = ((ViewValidationThrowable) throwable).mView; 
          //show dialog here 
         } 
        }, 
        () -> { 
         //everything valid 
        }); 
} 

private void dialogResult(CustomViewValidator view) { 
    view.setCondition(true); 
    validate(mViews); 
} 

在這個例子中,我們仍然需要我們想要做的驗證每次調用validate方法。

這裏是另一個我們不斷裂的例子。

private static class Pair<T,V> { 
    private final T first; 
    private final V second; 

    public Pair(T first, V second) { 
     this.first = first; 
     this.second = second; 
    } 
} 
private static class CustomViewValidator { 
    //Subject allows us: 
    // * probably not break chain later using some retry techniques 
    // * subject can be attach to other sources eg. EditText etc 
    //Of course it can be replaced with simple variable 
    BehaviorSubject<Boolean> mSubject = BehaviorSubject.create(); 

    Observable<Pair<Boolean,CustomViewValidator>> getValidationObservable() { 
     return mSubject.asObservable().map(s -> new Pair<>(s,CustomViewValidator.this)); 
    } 

    void setCondition(boolean v) { 
     mSubject.onNext(v); 
    } 
} 

private void validate(final List<Observable<Pair<Boolean, CustomViewValidator>>> viewObservables) { 
    //IMPORTANT do not forget to unsubscribe 
    // In this case we do not break our chain, so it can last forever 
    Subscription subsciption = Observable.combineLatest(viewObservables, 
      objects -> { 
       for (Object object : objects) { 
        Pair<Boolean, CustomViewValidator> viewPair = (Pair<Boolean, CustomViewValidator>) object; 
        if (!viewPair.first) { 
         return viewPair; 
        } 
       } 
       return new Pair<>(true, null); 
      }) 
      .subscribe(pair -> { 
       if (pair.first) { 
        //everything is valid DO NOT USE second argument here 
       } else { 
        //show dialog here using pair.second as View 
       } 
      }); 

} 

private void dialogResult(CustomViewValidator view) { 
    view.setCondition(true); 
    //no reason to call validate again 
    //setCondition will trigger chain again 
} 

對不起,我沒有測試過它。試圖給你不同方法的主要想法。這些方法主要基於已被接受的答案表達的想法。