sou*_*rar 8 validation android rx-java2
我有一个表格,有4个可能的选项需要检查(根据情况可能会更少).在创建订单时,有2个editexts,一个用于电子邮件,另一个用于参考字段.
电子邮件和参考字段可能会根据条件(在创建表单时可用)保留为空.此外,我们可能需要显示一个警告对话框,告诉用户可能无法显示参考值(对订单的收件人),他们可能还需要同意条款和条件警报对话框.
目前onConfirm检查是这样的,
void onCreateOrderConfirmed(@Nullable final String receiverEmail,
@Nullable final String reference,
@Nullable final Boolean noRefAgreed,
@Nullable final Boolean termsAndConditionsAgreed) {
if (!reviewCompletionState.emailRequirementSatisfied()) {
if (!isValidEmail(receiverEmail)) {
view.showEmailError();
return;
}
reviewCompletionState = reviewCompletionState.newBuilder()
.receiverEmail(receiverEmail)
.emailRequirementSatisfied(true)
.build();
}
if (!reviewCompletionState.referenceRequirementSatisfied()) {
if (isEmpty(reference)) {
view.showReferenceError();
return;
}
reviewCompletionState = reviewCompletionState.newBuilder()
.reference(reference)
.referenceRequirementSatisfied(true)
.build();
}
if (!reviewCompletionState.noRefAgreed()) {
if (noRefAgreed == null || !noRefAgreed) {
view.showNoReferenceAlert();
return;
}
reviewCompletionState = reviewCompletionState.newBuilder()
.noRefAgreed(true)
.build();
}
if (!reviewCompletionState.termsAndConditionsAgreed()) {
if (termsAndConditionsAgreed == null || !termsAndConditionsAgreed) {
view.showTermsDisclaimerAlert();
return;
}
reviewCompletionState = reviewCompletionState.newBuilder()
.termsAndConditionsAgreed(true)
.build();
}
createOrder();
}
Run Code Online (Sandbox Code Playgroud)
我想知道是否有办法使用RxJava2简化这个验证?(但目前还不知道能够做到这一点)
TIA
这可能很简单。将有很多代码,我将首先显示结果。
private ReviewValidator reviewValidator = new ReviewValidator();
void onCreateOrderConfirmed(@Nullable final String receiverEmail,
@Nullable final String reference,
@Nullable final Boolean noRefAgreed,
@Nullable final Boolean termsAndConditionsAgreed) {
ReviewState reviewState = new ReviewState(receiverEmail,
reference,
noRefAgreed,
termsAndConditionsAgreed);//another model for simplicity
reviewValidator.validate(reviewState)
.flatMap(reviewState -> /* create order */)
.subscribe(this::onOrderCreated, this::onOrderCreatingError);
}
void onOrderCreated(Object order) {//or what you need here
//handle positive result
}
void onOrderCreatingError(Throwable throwable) {
if (throwable instanceof ValidateException) {
List<ValidateError> errors = ((ValidateException) throwable).getValidateErrors();
for (ValidateError error: errors) {
switch (error.getField()) {
case EMAIL: {
view.showEmailError();
return;//or break if you want show all errors
}
case REFERENCE: {
view.showReferenceError();
return;
}
//handle another errors....
}
}
//handle another error cases...
}
Run Code Online (Sandbox Code Playgroud)
首先,为reviewState创建模型:
public class ReviewState {
private String receiverEmail;
private String reference;
private Boolean noRefAgreed;
private Boolean termsAndConditionsAgree;
public ReviewState(String receiverEmail,
String reference,
Boolean noRefAgreed,
Boolean termsAndConditionsAgree) {
this.receiverEmail = receiverEmail;
this.reference = reference;
this.noRefAgreed = noRefAgreed;
this.termsAndConditionsAgree = termsAndConditionsAgree;
}
public String getReceiverEmail() {
return receiverEmail;
}
public String getReference() {
return reference;
}
public Boolean getNoRefAgreed() {
return noRefAgreed;
}
public Boolean getTermsAndConditionsAgree() {
return termsAndConditionsAgree;
}
}
Run Code Online (Sandbox Code Playgroud)
然后创建您自己的验证器。不必创建整个模型,可以为每个字段创建验证器,然后将其与您选择的flatMap()链接。
public class ReviewValidator extends Validator<ReviewState> {
@Override
protected List<ValidateFunction> getValidateFunctions(ReviewState reviewState) {
List<ValidateFunction> validateFunctions = new LinkedList<>();
validateFunctions.add(() -> validateEmail(reviewState.getReceiverEmail()));
validateFunctions.add(() -> validateReference(reviewState.getReference()));
//another validation methods
return validateFunctions;
}
private ValidateError validateEmail(String email) {
if (TextUtils.isEmpty(email)) {
return new ValidateError(Field.EMAIL);//Field.EMAIL - just enum
}
return null;
}
private ValidateError validateReference(String reference) {
if (TextUtils.isEmpty(reference)) {
return new ValidateError(Field.REFERENCE);
}
return null;
}
//....
//another validation methods
}
Run Code Online (Sandbox Code Playgroud)
验证器的抽象类:
public abstract class Validator<Model> {
public Single<Model> validate(Model model) {
return Single.just(model)
.map(this::validateModel)
.flatMap(this::processResult);
}
private Single<Model> processResult(ValidateResultModel<Model> validateResultModel) {
return Single.create(subscriber -> {
List<ValidateError> validateErrors = validateResultModel.getValidateErrors();
if (validateErrors.isEmpty()) {
subscriber.onSuccess(validateResultModel.getModel());
} else {
subscriber.onError(new ValidateException(validateErrors));
}
});
}
private ValidateResultModel<Model> validateModel(Model model) {
List<ValidateError> errors = new LinkedList<>();
for (ValidateFunction validateFunctions : getValidateFunctions(model)) {
ValidateError error = validateFunctions.validate();
if (error != null) {
errors.add(error);
}
}
return new ValidateResultModel<>(model, errors);
}
protected abstract List<ValidateFunction> getValidateFunctions(Model model);
protected interface ValidateFunction {
@Nullable
ValidateError validate();
}
}
Run Code Online (Sandbox Code Playgroud)
验证程序的帮助程序类...
public class ValidateError {
private Field field;
public ValidateError(Field field) {
this.field = field;
}
public Field getField() {
return field;
}
}
class ValidateResultModel<T> {
private T model;
private List<ValidateError> validateErrors;
ValidateResultModel(T model, List<ValidateError> validateErrors) {
this.model = model;
this.validateErrors = validateErrors;
}
T getModel() {
return model;
}
List<ValidateError> getValidateErrors() {
return validateErrors;
}
}
public class ValidateException extends RuntimeException {
private List<ValidateError> validateErrors;
ValidateException(List<ValidateError> validateErrors) {
this.validateErrors = validateErrors;
}
public List<ValidateError> getValidateErrors() {
return validateErrors;
}
}
Run Code Online (Sandbox Code Playgroud)
最初,我从这里接受了这个想法:https : //github.com/matzuk/TestableCodeMobius/tree/master/app/src/main/java/com/matsyuk/testablecodemobius/business/transfer/validation
我认为你应该 RxJava CoupleLatest,所以你需要所有的表单输入都生成一个可观察的,然后你只需将它组合起来并调整视图
作为参考,您可以检查:
https://medium.com/@etiennelawlor/rxjava-on-the-sign-in-screen-9ecb66b88572
使用 RxJava 进行电子邮件登录验证,可观察对象发出两次
========
例子:
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.widget.Button;
import android.widget.CheckBox;
import android.widget.EditText;
import android.widget.Toast;
import com.jakewharton.rxbinding2.view.RxView;
import com.jakewharton.rxbinding2.widget.RxCompoundButton;
import com.jakewharton.rxbinding2.widget.RxTextView;
import io.reactivex.Observable;
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
EditText receiverText = findViewById(R.id.input_receiver);
EditText referenceText = findViewById(R.id.input_reference);
CheckBox checkRef = findViewById(R.id.check_ref);
CheckBox checkTerms = findViewById(R.id.check_terms);
Button buttonLogin = findViewById(R.id.button_login);
Observable<CharSequence> receiverObservable = RxTextView.textChanges(receiverText).skip(1); // can add more logic
Observable<CharSequence> referenceObservable = RxTextView.textChanges(referenceText).skip(1); // can add more logic
Observable<Boolean> refCheckObservable = RxCompoundButton.checkedChanges(checkRef); // can add more logic
Observable<Boolean> termsCheckObservable = RxCompoundButton.checkedChanges(checkTerms); // can add more logic
Observable<String> combineObservable = Observable.combineLatest(
receiverObservable,
referenceObservable,
refCheckObservable,
termsCheckObservable, (receiverCharSequence, referenceCharSequence, refBoolean, termsBoolean) -> {
// add logic here for now it is only combine the input
return receiverCharSequence + " " + referenceCharSequence + " " + refBoolean + " " + termsBoolean ;}
);
RxView.clicks(buttonLogin).flatMap(o -> { return combineObservable;}).distinctUntilChanged().subscribe(string -> {
Toast.makeText(this, string, Toast.LENGTH_LONG).show();
});
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1101 次 |
| 最近记录: |