RxJava/RxAndroid-обработка нескольких изменений EditText
у меня есть 3 поля EditText и я создал 3 наблюдаемых для этих полей.
Observable<CharSequence> o1 = RxTextView.textChanges(field1);
Observable<CharSequence> o2 = RxTextView.textChanges(field2);
Observable<CharSequence> o3 = RxTextView.textChanges(field3);
Я хочу включить кнопку, когда все эти три поля имеет значение. пользователь может вводить значения в любом порядке в полях. Как я могу это сделать?
редактировать
я использовал zip для достижения этого.
Observable<CharSequence> o1 = RxTextView.textChanges(field1);
Observable<CharSequence> o2 = RxTextView.textChanges(field2);
Observable<CharSequence> o3 = RxTextView.textChanges(field3);
Observable.zip(o1, o2, o3, (c1, c2, c3) -> c1.length() > 0 && c2.length() > 0 && c3.length() > 0).subscribe(myButton::setEnabled)
этот случай выше работает, когда я ввожу что-то во всех трех текстовых полях. например, я ввел 1 символ во всех трех текстовых полей, то кнопка будет быть включена. Но когда я удаляю символ в любом из трех полей. zip не будет вызываться, поскольку он будет ждать, пока другие 2 текстовых поля перед вызовом onNext на подписчике передадут некоторые данные. поэтому, когда я удаляю любой символ в любом текстовом поле, я хочу, чтобы моя кнопка снова отключилась. Как я могу этого достичь?
2 ответов
использовать CombineLatest
вместо zip
http://reactivex.io/documentation/operators/combinelatest.html
попробуйте это, это определенно сработает. используйте combineLatest.
//declare global variable
private Subscription subscription = null;
Observable<CharSequence> o1 = RxTextView.textChanges(field1);
Observable<CharSequence> o2 = RxTextView.textChanges(field2);
public void combineEvent(){
subscription = Observable.combineLatest(o1, o2,
new Func2<CharSequence, CharSequence, Boolean>() {
@Override public Boolean call(CharSequence newEmail, CharSequence newPassword) {
//here you can validate the edit text
boolean emailValid= !TextUtils.isEmpty(newEmail)
&& android.util.Patterns.EMAIL_ADDRESS.matcher(newEmail).matches();
if(!emailValid){
etEmailAddress.setError("Invalid Email");
}
boolean passValid = !TextUtils.isEmpty(newPassword)
&& newPassword.length() >6;
if(!passValid){
etPassword.setError("invalid password");
}
return emailValid && passValid;
}
}).subscribe(new Observer<Boolean>() {
@Override public void onCompleted() {
}
@Override public void onError(Throwable e) {
}
@Override public void onNext(Boolean aBoolean) {
if(aBoolean){
//here you can enable your button or what ever you want.
loginBtn.setEnabled(true);
}else {
loginBtn.setEnabled(false);
}
}
});
}