2016-03-04 75 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 
} 

对不起,我没有测试过它。试图给你不同方法的主要想法。这些方法主要基于已被接受的答案表达的想法。