寫在前面
在平時的開發(fā)中梅掠,處理表單也是需要注意的檻酌住。
開發(fā)者一般都會有自己的一套處理表單的方法店归,以前都會自己手動添加textChangeListener,到后來會通過Rxjava亦或者更直接的Rxbinding來處理,可以參考鏈接RxJava處理復(fù)雜表單驗證問題赂韵。
當然還有一些表單驗證的庫娱节。
這些都是大家熟知的事情,不多談祭示,本文主要探討另外一種處理表單的方法肄满。
使用DataDinding來處理表單驗證問題
關(guān)于DataBinding前幾篇就有介紹,不了解的可以搜索一下质涛,easy稠歉。
處理表單驗證,關(guān)鍵是需要獲取到填充的數(shù)據(jù)汇陆,然后驗證格式是否正確怒炸,平常都是根據(jù)textChangeListener,而dataBinding可以使用雙向綁定輕松拿到。
<AutoCompleteTextView
android:id="@+id/username"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="@string/prompt_username"
android:inputType="text"
android:maxLines="1"
android:text="@={vm.username}"/>
接下來是驗證
public static final String PASSWORD_PATTERN = "^[a-zA-Z0-9_]{6,16}$";
public static final String USERNAME_PATTERN = "^[a-zA-Z0-9_]{6,16}$";
private static final String EMAIL_PATTERN =
"^[a-zA-Z0-9#_~!$&'()*+,;=:.\"(),:;<>@\\[\\]\\\\]+@[a-zA-Z0-9-]+(\\.[a-zA-Z0-9-]+)*$";
private String username = "";
private String email = "";
private String password = "";
private Pattern usernamePattern = Pattern.compile(USERNAME_PATTERN);
private Pattern emailPattern = Pattern.compile(EMAIL_PATTERN);
private Pattern passwordPattern = Pattern.compile(PASSWORD_PATTERN);
@Bindable({"username", "password", "email"})
public boolean isBtnEnabled() {
if (!usernamePattern.matcher(username).matches()|| !emailPattern.matcher(email).matches()
|| !passwordPattern.matcher(password).matches()) {
return false;
}
return true;
}
使用正則表達式來驗證格式是否正確
isBtnEnabled()用來判斷按鈕是否可點擊
@Bindable({"username", "password", "email"})是databinding的Dependent Properties毡代,在"username", "password", "email"這幾個值改變的時候通知isBtnEnabled()方法返回更新的值阅羹,具體可以參考前面的文章【譯】Android Data Binding: Dependent Properties。
效果如下:
![SingleMode.gif](https://github.com/ditclear/BaseViewBinding/blob/master/validate.gif?raw=true)
錯誤處理
在點擊Sign In 后 教寂,可能登錄失敗捏鱼,提示用戶名或者密碼錯誤,需要通過setError()方法來提示用戶酪耕。不過TextInputLayout不是那么智能导梆,具體見使用TextInputLayout創(chuàng)建一個登陸界面 ,可能需要大量的無用的代碼迂烁。
public void onClick(View v) {
hideKeyboard();
String username = usernameWrapper.getEditText().getText().toString();
String password = usernameWrapper.getEditText().getText().toString();
if (!validateEmail(username)) {
usernameWrapper.setError("Not a valid email address!");
} else if (!validatePassword(password)) {
passwordWrapper.setError("Not a valid password!");
} else {
usernameWrapper.setErrorEnabled(false);
passwordWrapper.setErrorEnabled(false);
doLogin();
}
}
而使用Databinding我們不必需要寫這么多格式化的無用代碼看尼,直接在xml里設(shè)置就好了。
<android.support.design.widget.TextInputLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:error="@{vm.usernameError}"
app:errorEnabled="@{vm.usernameInValid}"
app:errorTextAppearance="@color/login_error">
<AutoCompleteTextView
android:id="@+id/username"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="@string/prompt_username"
android:inputType="text"
android:maxLines="1"
android:text="@={vm.username}"/>
</android.support.design.widget.TextInputLayout>
TextInputLayout有setError和setErrorEnabled兩個方法盟步,我們只需要改變viewmodel里的值藏斩,就可以達到相應(yīng)的效果。
private String usernameError = "";
private String passwordError = "";
private String emailError = "";
//get set method
@Bindable("usernameError")
public boolean isUsernameInValid() {
return !isEmpty(usernameError);
}
@Bindable("emailError")
public boolean isEmailInValid() {
return !isEmpty(emailError);
}
@Bindable("passwordError")
public boolean isPasswordInValid() {
return !isEmpty(passwordError);
}
//···
看看效果:
![error.gif](https://github.com/ditclear/BaseViewBinding/blob/master/error.gif?raw=true)
寫在最后
處理表單平常還是用rxjava 用的比較多却盘,前幾天發(fā)現(xiàn)databinding處理也很簡單灾茁,相信databinding還會有更多很贊的地方等待大家發(fā)掘。
githud地址:https://github.com/ditclear/BaseViewBinding/tree/master/app/src/main/java/com/ditclear/app/validate