Makis Mandrelas Makis Mandrelas - 3 years ago 62
Android Question

Create a uniform Action1 to perform checks on fields

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);


I have created an Action1 whose responsibility is to check the state of the model and change the color of the button, created subscriptions equal to the number of Observables and passed it as a parameter.

Something like this for example

Action1<CharSequence> lengthCheck = new Action1<CharSequence>() {
@Override
public void call(CharSequence charSequence) {
if(field is name){
if(charSequence.length() > 5)
...
}
...
}
};


So my question is , is there a way to succeed something similar to this for the Action1 that check the length ? Is it even the correct place to put a check like this? It just seems silly to me that I have the exact same code , copy and pasted three times with minimal changes.
Thanks a lot for your time.

Answer Source

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);
}
Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download