首页 > 解决方案 > 使用绑定适配器进行验证

问题描述

我需要一些了解绑定适配器实现的概念。

我正在设计一个带有两个输入字段和一个按钮的登录表单。我正在尝试使用绑定适配器来使用文本观察器验证这些字段(工作正常)。

但是我不知道如何在单击按钮时验证这些字段。我正在尝试实现一个干净的架构并消除视图和 ViewModel 之间的所有类型的依赖关系。

login_activity.xml

<layout xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools">

    <data>
    <variable
        name="authModel"
        type="com.jpm.ui.auth.AuthViewModel" />
</data>


<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"

    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@color/colorSurface"
    tools:context=".ui.auth.LoginActivty">

    <androidx.appcompat.widget.AppCompatImageView
        android:id="@+id/logo"
        android:layout_width="match_parent"
        android:layout_height="150dp"
        android:layout_marginTop="60dp"
        app:layout_constraintTop_toTopOf="parent"
        app:srcCompat="@drawable/jpm_logo" />


    <com.google.android.material.textfield.TextInputLayout
        android:id="@+id/layoutLoginId"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginStart="40dp"
        android:layout_marginTop="40dp"
        android:layout_marginEnd="40dp"
        android:hint="@string/login_id_hint"
        app:layout_constraintTop_toBottomOf="@id/logo"
        app:startIconDrawable="@drawable/ic_user"
        nullCheck="@{@string/nullError}">

        <com.google.android.material.textfield.TextInputEditText
            android:id="@+id/inputLoginId"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="@={authModel.inputLoginId}" />

    </com.google.android.material.textfield.TextInputLayout>

    <com.google.android.material.textfield.TextInputLayout
        android:id="@+id/layoutPassword"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginStart="40dp"
        android:layout_marginTop="10dp"
        android:layout_marginEnd="40dp"
        android:hint="@string/password"
        app:layout_constraintTop_toBottomOf="@id/layoutLoginId"
        app:passwordToggleEnabled="true"
        app:startIconDrawable="@drawable/ic_locked">

        <com.google.android.material.textfield.TextInputEditText
            android:id="@+id/inputPassword"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="@={authModel.inputPassword}" />
    </com.google.android.material.textfield.TextInputLayout>

    <com.google.android.material.button.MaterialButton
        android:id="@+id/btnSignIn"
        android:layout_width="wrap_content"
        android:layout_height="40dp"
        android:layout_marginTop="30dp"
        android:background="@drawable/bg_primary_rounded"
        android:onClick="@{authModel::authClickListener}"
        android:paddingStart="40dp"
        android:paddingEnd="40dp"
        android:text="@string/sign_in"
        android:textColor="@color/textSecondary"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toBottomOf="@id/layoutPassword" />

    <com.google.android.material.textview.MaterialTextView
        android:id="@+id/labelCreateAccount"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="20dp"
        android:text="@string/don_t_have_an_account"
        app:layout_constraintHorizontal_chainStyle="packed"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toLeftOf="@id/txtCreateAccount"
        app:layout_constraintTop_toBottomOf="@id/btnSignIn" />

    <com.google.android.material.textview.MaterialTextView
        android:id="@+id/txtCreateAccount"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginStart="5dp"
        android:layout_marginTop="20dp"
        android:onClick="@{authModel::authClickListener}"
        android:text="@string/create_account"
        android:textColor="@color/colorPrimary"
        app:layout_constraintHorizontal_chainStyle="packed"
        app:layout_constraintLeft_toRightOf="@id/labelCreateAccount"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toBottomOf="@id/btnSignIn" />

    <com.google.android.material.textview.MaterialTextView
        android:id="@+id/txtSkip"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="20dp"
        android:onClick="@{authModel::authClickListener}"
        android:text="@string/skip"
        android:textColor="@color/textGrey"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toBottomOf="@id/txtCreateAccount" />

</androidx.constraintlayout.widget.ConstraintLayout>

ValidationUtils.class

import android.util.Log
import androidx.core.widget.doAfterTextChanged
import androidx.databinding.BaseObservable
import androidx.databinding.Bindable
import androidx.databinding.BindingAdapter
import com.google.android.material.textfield.TextInputEditText
import com.google.android.material.textfield.TextInputLayout
import com.google.common.base.Predicates
import com.jpm.R

object ValidationUtils : BaseObservable() {

    const val TAG = "VALIDATION"

    @BindingAdapter("nullCheck")
    @JvmStatic
    fun setError(inputLayout: TextInputLayout, errorMsg: String) {
        inputLayout.editText?.doAfterTextChanged {
            if (it.isNullOrEmpty()) {
                inputLayout.isErrorEnabled = true
                inputLayout.error = errorMsg
            } else {
                inputLayout.isErrorEnabled = false
                inputLayout.error = null
            }
        }
    }

}

请提供一些建议或我可以实施什么来实现按钮单击验证。

**PS - 按钮点击验证setError也应该应用EditText**

标签: androidmvvmandroid-databinding

解决方案


这就是我在你的情况下使用的:

当您的 ViewModelauthClickListener()被调用时,您检查/验证与双向数据绑定绑定的每个输入,在您的情况下inputLoginIdpassword.

此外,您设置了两个错误可观察对象,其 typeString?error各自的相关TextInputLayout,并根据您的验证逻辑修改错误消息


推荐阅读