我正在尝试创建一个表单,仅发送视图,该视图具有SignaturePad,一旦用户单击保存按钮,就会触发保存意图并进行一些后台处理。
我有以下几点:
主持人:
@Override
protected void bindIntents() {
Observable<SignatureViewState> observable =
intent(SignatureView::saveSignature)
.switchMap(intent -> Observable.fromCallable(() ->
storage.createFile(intent.getFullPath(), intent.getName(), intent.getImage()))
.subscribeOn(Schedulers.from(threadExecutor)))
.map(SignatureViewState.SuccessState::new)
.cast(SignatureViewState.class)
.startWith(new SignatureViewState.LoadingState())
.onErrorReturn(SignatureViewState.ErrorState::new)
.observeOn(postExecutionThread.getScheduler());
subscribeViewState(observable, SignatureView::render);
}
签名片段:
@Override
public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
saveButtonClickObservable = RxView.clicks(saveBtn)
.share()
.map(bla -> true);
compositeDisposable.add(saveButtonClickObservable.subscribe());
。
@Override
public Observable<SaveSignatureIntent> saveSignature() {
Observable<SaveSignatureIntent> saveSignatureIntentObservable =
Observable.just(new SaveSignatureIntent(savePath, bookingId + ".png", null));
Observable<SaveSignatureIntent> saveSignatureIntent =
Observable.zip(signatureBitmapObservable, saveSignatureIntentObservable,
(signature, intent) -> new SaveSignatureIntent(intent.fullPath, intent.name, signature));
return saveButtonClickObservable
.flatMap(bla -> saveSignatureIntent);
}
@Override
public void render(SignatureViewState state) {
if(state instanceof SignatureViewState.LoadingState)
renderLoading();
else if (state instanceof SignatureViewState.SuccessState)
renderSuccess();
if(state instanceof SignatureViewState.ErrorState)
renderError();
}
最后我的观点是:
public interface SignatureView extends MvpView {
Observable<SignatureFragment.SaveSignatureIntent> saveSignature();
void render(SignatureViewState state);
}
问题是,一旦我的碎片被创建,.startWith 就会被触发,而无需用户单击按钮。之后,如果用户单击按钮,则永远不会调用加载状态(再次调用.startwith(,而只会调用成功(或错误(。我在这里错过了什么?
再次感谢 !
编辑:
signatureBitmapObservable = Observable.fromCallable(() -> signaturePad.getTransparentSignatureBitmap(true))
.subscribeOn(Schedulers.io())
.startWith(bla -> renderLoading());
另一个过程是获取透明位图,但是在添加 startWith 后,我的可调用对象永远不会被调用。如果我把它拿出来,它就像一个魅力。
这只是一个RxJava错误,与Mosby无关。
将.startWith(new SignatureViewState.LoadingState())
(也许.onErrorReturn(SignatureViewState.ErrorState::new)
(放入从switchMap()
返回的可观察量中。喜欢这个:
intent(SignatureView::saveSignature)
.switchMap(intent -> Observable.fromCallable(() ->
storage.createFile(intent.getFullPath(), intent.getName(), intent.getImage()))
.subscribeOn(Schedulers.from(threadExecutor))
.map(SignatureViewState.SuccessState::new)
.cast(SignatureViewState.class)
.startWith(new SignatureViewState.LoadingState())
.onErrorReturn(SignatureViewState.ErrorState::new)
) // end of switchMap
.observeOn(postExecutionThread.getScheduler());
从 switchMap 返回的可观察量仅在用户单击您的按钮后启动(因为 switchMap 仅在触发意图后触发(。
startWith()
的意思是"在你做真正的工作之前,先发出这个"。如果你像在原始代码中那样应用 startWith((,显然它是从加载开始的可观察的开始,但你真正想要的是"在保存签名之前,从加载状态开始"。因此,startWith()
必须是"保存签名"可观察对象的一部分,而不是"主要"可观察对象本身的一部分。