Android UI线程上的链接RxJava调用
我正在尝试学习一些RxJava和RxAndroid,我认为我遇到的问题可以用这样的工具轻松解决。问题是: 我们可以在一个活动中拥有“N”个视图,并且每个视图都用于满足某些条件。当用户按下“保存”时,我们要检查所有视图中是否满足所有条件,如果不满足,请用户分别确认每个视图。 下面是一个没有RxJava我如何处理这个问题的例子:Android UI线程上的链接RxJava调用,android,rx-java,rx-android,Android,Rx Java,Rx Android,我正在尝试学习一些RxJava和RxAndroid,我认为我遇到的问题可以用这样的工具轻松解决。问题是: 我们可以在一个活动中拥有“N”个视图,并且每个视图都用于满足某些条件。当用户按下“保存”时,我们要检查所有视图中是否满足所有条件,如果不满足,请用户分别确认每个视图。 下面是一个没有RxJava我如何处理这个问题的例子: private void validation(List<CustomView> views) { for (CustomView view : vie
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);
}
private void验证(列表视图)
{
用于(自定义视图:视图)
{
if(view.metCondition()==false)
{
显示确认对话框(视图);
返回false;
}
}
返回true;
}
私有无效显示确认对话框(自定义视图)
{
确认对话框=新建确认对话框(此视图);
dialog.show();
}
私有无效对话框结果(自定义视图)
{
view.setCondition(true);
验证(mViews);
}
显然,我需要某种类型的监听器来确认结果,并且在条件被确认(使用OK或Cancel)后,“view.metCondition()”将被设置为true,这样它就不会再次针对该视图弹出。当然,在“validation”返回true之后,它将运行“Save()”函数
这是我真正的解决方案,因为我想让它尽可能简单,所以如果您知道如何使用RxJava实现类似的功能,请发表评论。我已经在使用这个库来做一些异步的事情(与usb连接的设备交谈),所以我知道一些事情,但从来都不知道如何像这样链接调用
非常感谢您的帮助
编辑
添加了listener方法,这样我们就可以看到“validate()”函数再次被调用对于链式验证,您应该仔细查看
combinelatetest()
。首先,为每个视图创建可观察的,然后使用该操作符。是Android视图的优秀扩展
参见示例。这是一个很好的验证方法。再举一个灵感的例子:)
对不起,我没有测试。只是想告诉你不同方法的主要思想。这些方法在很大程度上基于公认答案中已经表达的观点。这是一个很好的例子,说明了我的需要,但我花了一些时间才真正意识到这一点。非常感谢你。
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);
}
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
}