MVVM架构下如何在ViewModel层实现TextInputLayout的校验错误绑定
实现方案
步骤1:自定义DataBinding适配方法
由于DataBinding默认没有对TextInputLayout的error属性做映射绑定,我们需要通过@BindingAdapter自定义绑定逻辑,创建全局绑定适配类即可:
import androidx.databinding.BindingAdapter; import com.google.android.material.textfield.TextInputLayout; public class GlobalBindingAdapters { @BindingAdapter("android:error") public static void setTextInputError(TextInputLayout textInputLayout, String errorMsg) { textInputLayout.setError(errorMsg); } }
步骤2:修改ViewModel新增可观察错误字段
在ViewModel中新增对应字段的错误信息可观察属性,校验后仅更新该属性值,不持有任何View引用:
public class LoginViewModel extends BaseObservable { private static final String TAG = "LoginViewModel"; private String loginEmail; // 新增邮箱错误信息可观察字段 private String loginEmailError; @Bindable public String getLoginEmail() { return loginEmail; } public void setLoginEmail(String loginEmail) { this.loginEmail = loginEmail; notifyPropertyChanged(BR.loginEmail); } @Bindable public String getLoginEmailError() { return loginEmailError; } public void setLoginEmailError(String loginEmailError) { this.loginEmailError = loginEmailError; notifyPropertyChanged(BR.loginEmailError); } // 调整校验方法逻辑 public void validate(String text, Validator validator){ if(!validator.validate(text)){ // 校验不通过赋值错误信息 setLoginEmailError(validator.getInvalidMsg()); } else { // 校验通过清空错误 setLoginEmailError(null); } } }
步骤3:布局中绑定错误属性
给TextInputLayout新增android:error属性,绑定到ViewModel对应的错误字段即可:
<com.google.android.material.textfield.TextInputLayout android:id="@+id/fragment_login_til_email" style="@style/App_TextInputEditTextStyle" android:layout_marginBottom="@dimen/et_space_0" android:error="@{viewmodel.loginEmailError}"> <com.google.android.material.textfield.TextInputEditText style="@style/App_TextInputEditTextStyle" android:inputType="textEmailAddress" android:hint="Email Address" android:autofillHints="emailAddress" android:text="@={viewmodel.loginEmail}" android:afterTextChanged="@{() -> viewmodel.validate(viewmodel.loginEmail, validator.REQUIRED_FIELD)}"/> </com.google.android.material.textfield.TextInputLayout>
逻辑说明
整个流程完全符合MVVM职责划分:
- 用户输入变更触发校验逻辑,全部在ViewModel层执行
- 校验完成后ViewModel仅更新错误数据字段,不直接操作View
- DataBinding检测到可观察字段变更后,自动触发我们自定义的BindingAdapter方法,完成
TextInputLayout的错误提示更新,全程不需要Fragment介入操作View
如果后续需要新增其他字段的校验,比如密码,只需要在ViewModel中新增对应passwordError可观察字段,绑定到对应TextInputLayout的error属性即可,逻辑完全复用。
内容的提问来源于stack exchange,提问作者Gene
相关产品推荐
相关产品推荐

