I was trying to get familiar with RxBinding and how it could be applied on simple forms. I was wondering if there is way to create one Action1 that performs the checks and updates the model. If I am not clear enough I hope the code below will help you understand what I mean.
Observable<CharSequence> nameObservable = RxTextView.textChanges(name).share();
Action1<CharSequence> validateAction;
Observable<CharSequence> surnameObservable = RxTextView.textChanges(surname).share();
Observable<CharSequence> emailObservable = RxTextView.textChanges(mail).share();
validateAction = new Action1<CharSequence>() {
@Override
public void call(CharSequence charSequence) {
if(state.nameState && state.surnameState && state.emailState)
submit.setBackgroundColor(getResources().getColor(R.color.green));
else
submit.setBackgroundColor(getResources().getColor(R.color.blue));
}
};
Subscription nameState = nameObservable
.subscribe(new Action1<CharSequence>() {
@Override
public void call(CharSequence charSequence) {
Log.d("Length","Len : " + charSequence.length());
if(charSequence.length() > 5)
state.nameState = true;
else
state.nameState = false;
}
});
Subscription surnameState = surnameObservable
.subscribe(new Action1<CharSequence>() {
@Override
public void call(CharSequence charSequence) {
Log.d("Length","Len : " + charSequence.length());
if(charSequence.length() > 5)
state.surnameState = true;
else
state.surnameState = false;
}
});
Subscription mailState = emailObservable
.subscribe(new Action1<CharSequence>() {
@Override
public void call(CharSequence charSequence) {
Log.d("Length","Len : " + charSequence.length());
if(charSequence.length() > 5)
state.emailState = true;
else
state.emailState = false;
}
});
Subscription nameValidate = nameObservable.subscribe(validateAction);
Subscription surnameValidate = surnameObservable.subscribe(validateAction);
Subscription mailValidate = emailObservable.subscribe(validateAction);
Action1<CharSequence> lengthCheck = new Action1<CharSequence>() {
@Override
public void call(CharSequence charSequence) {
if(field is name){
if(charSequence.length() > 5)
...
}
...
}
};
For name validation
private Observable<Boolean> getNameObservable() {
return RxTextView.textChanges(name)
.map(charSequence -> charSequence.toString().trim().length() > 0);
}
For surname validation
private Observable<Boolean> getSurNameObservable() {
return RxTextView.textChanges(email)
.map(charSequence -> charSequence.toString().trim().length() > 0);
}
For email validation
private Observable<Boolean> getEmailObservable() {
return RxTextView.textChanges(email)
.map(charSequence -> charSequence.toString().trim().length() > 0);
}
Using combineLatest
to combine 3 observables as 1 stream
Observable.combineLatest(getNameObservable(),getSurNameObservable(), getEmailObservable,
(nameValid, surnameValid,emailValid) -> nameValid && surnameValid && emailValid)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(isAllFieldsValid ->
enableButton(yourButton, isAllFieldsValid));
The enable function
private void enableButton(Button button, boolean isAvailable) {
button.setEnabled(isAvailable);
if (isAvailable) {
button.setBackgroundResource(R.drawable.green);
} else {
button.setBackgroundResource(R.drawable.blue);
}
}
=========================================================================
PS: You can create a function that create an Observable for 3 EditText
private Observable<Boolean> getNameObservable(EditText et) {
return RxTextView.textChanges(et)
.map(charSequence -> charSequence.toString().trim().length() > 0);
}