このため、外部の関係を引き上げることは冗長に思えます。 たとえば、同じHibernate Validatorは、最終的なapkの重みに約8000個のメソッドと1 mbを追加しますが、これは...冗長に見えます)
インターネット上でいくつかの成功したソリューションの検索が失敗したため、独自のファイルを提出することにしました。 同僚と(iOSの指示に従って)相談した後、彼らは簡潔なソリューションのアイデアを思いつきました。その後、それは各プラットフォームに実装されました。
このアイデアの実装をAndroidで共有したいと思います。 しかし、私はすぐにあなたに警告します、アイデアの認識の単純さのために、使用例は非常に単純なバージョンで、おそらくは素朴でさえ与えられるでしょう。 さらに、現在のアイデアの実装ではRxを使用していません。
だから。 すべては、非常にシンプルなインターフェイスから始まります。
public interface Validator<T> { boolean isValid(T value); String getDescription(); }
実際、それだけです)
次に、同じ型のアトミックバリデーターを一緒に構築するための実装が必要です。
public class ValidatorsComposer<T> implements Validator<T> { private final List<Validator<T>> validators; private String description; public ValidatorsComposer(Validator<T>... validators) { this.validators = Arrays.asList(validators); } @Override public boolean isValid(T value) { for (Validator<T> validator : validators) { if (!validator.isValid(value)) { description = validator.getDescription(); return false; } } return true; } @Override public String getDescription() { return description; } }
例は、電子メールフィールドの検証です。 これを行うには、2つのアトミックバリデーターを作成します。
public class EmptyValidator implements Validator<String> { @Override public boolean isValid(String value) { return !TextUtils.isEmpty(value); } @Override public String getDescription() { return "Field must not be empty"; } }
public class EmailValidator implements Validator<String> { @Override public boolean isValid(String value) { return Patterns.EMAIL_ADDRESS.matcher(value).matches(); } @Override public String getDescription() { return "Email should be in \'a@a.com\' format"; } }
そして、実際には、ユースケース:
final ValidatorsComposer<String> emailValidatorsComposer = new ValidatorsComposer<>(new EmptyValidator(), new EmailValidator()); button.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { if (emailValidatorsComposer.isValid(emailEditText.getText().toString())) { errorTextView.setText(null); } else { errorTextView.setText(emailValidatorsComposer.getDescription()); } } });
このアイデアは、DataObjectsを検証し、画面にエラーを表示するのにも適しています。 たとえば、ユーザーDataObjectのバリデーターを作成します。
public class User { public final String name; public final Integer age; public final Gender gender; public enum Gender {MALE, FEMALE} public User(String name, Integer age, Gender gender) { this.name = name; this.age = age; this.gender = gender; } }
public class UserValidator implements Validator<User> { private String description; @Override public boolean isValid(User value) { if (value == null) { description = "User must not be null"; return false; } final String name = value.name; if (TextUtils.isEmpty(name)) { description = "User name must not be blank"; return false; } final Integer age = value.age; if (age == null) { description = "User age must not be blank"; return false; } else if (age < 0) { description = "User age must be above zero"; return false; } else if (age > 100) { description = "User age is to much"; return false; } final User.Gender gender = value.gender; if (gender == null) { description = "User gender must not be blank"; return false; } return true; } @Override public String getDescription() { return description; } }
そしてユースケース:
final Validator<User> userValidator = new UserValidator(); button.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { User user = new User(null, 12, User.Gender.MALE); if (userValidator.isValid(user)) { errorTextView.setText(null); } else { errorTextView.setText(userValidator.getDescription()); } } });
検証オプションは、イベントの検証(上記の例に示すようにボタンを押すなど)から、動的な検証(テキスト入力時)まで大きく異なります。
emailEditText.addTextChangedListener(new SimpleTextWatcher() { @Override public void afterTextChanged(Editable s) { if (!emailValidatorsComposer.isValid(s.toString())) { errorTextView.setText(emailValidatorsComposer.getDescription()); } } });
エラーを表示するための戦略だけでなく、エラーテキストを表示してキーボードを表示する(私の意見では望ましい)エラーフィールドに焦点を当てることから、画面上にすべてのエラーを一度に表示すること(これは、Androidアプリケーションでよくあることです) エラーを表示するためのGoogleの推奨事項はこちらにあります 。
その結果、フィールドとデータオブジェクトを検証するという非常にシンプルで柔軟なアイデアを得ることができます。これは実際、プロジェクトに少し負担をかけることなく、指をクリックするだけで実装されます。 利益を得る方法)