使用livedata的Android数据指标 - 一起验证多个字段



我正在使用ViewModel内部使用Livedata的双向数据指标来处理注册表单。

当填写字段时,需要将一些字段一起评估以获得有效性(以及整体形式),并且只有在一切正确的情况下才能启用提交按钮。

使用常规的Observable对象并使用@Bindable,只需注释所需的每个验证的'getter'函数,这将是简单的,并执行必要的验证步骤并返回每个功能内的适当结果。

,但我正在与Livedata合作。我想出了使用MediatoLiveData的解决方案(请参阅下面的基本示例),但在我看来,就像还有另一种更好的方法。

class RegistrationViewModel : ViewModel() {
    val email: MutableLiveData<String> by lazy { MutableLiveData<String>() }
    val emailConf: MutableLiveData<String> by lazy { MutableLiveData<String>() }
    val emailValid: MediatorLiveData<Boolean> = MediatorLiveData()
    val emailChanged: (Any) -> Unit = cc@ {
        //Obviously there is more validation needed but this is just an example
        if (email.value != null && emailConf.value != null) {
            emailValid.value = email.value.isNotEmpty() && emailConf.value.isNotEmpty() && email.value == emailConf.value
            return@cc
        }
        emailValid.value = false
    }
    init {
        emailValid.addSource(email, emailChanged)
        emailValid.addSource(emailConf, emailChanged)
    }
}

将其绑在UI上,例如,按钮的enabled属性或标签的visibility属性可以适当地绑定到emailValid属性。

您的方法正确,但是代码有一些设计问题:

  • lazy字段在init部分中使用。田野变得懒惰
  • emailValid字段可以以LiveData
  • 暴露
  • 验证可以封装在内部类中,但不需要

    class RegistrationViewModel : ViewModel() {
        val email = MutableLiveData<String>()
        val emailConf = MutableLiveData<String>()
        @Suppress("UNCHECKED_CAST")
        val emailValid: LiveData<Boolean> = MediatorLiveData<Boolean>().apply {
            val validator = Validator(::postValue)
            addSource(email, validator as Observer<String>)
            addSource(emailConf, validator as Observer<String>)
        }
        private inner class Validator(private val validationConsumer: (Boolean) -> Unit) : Observer<Any> {
            override fun onChanged(ignored: Any?) {
                //Obviously there is more validation needed but this is just an example
                val email = email.value
                val emailConf = emailConf.value
                validationConsumer(when {
                    email.isNullOrEmpty() -> false
                    emailConf.isNullOrEmpty() -> false
                    email == emailConf -> true
                    else -> false
                })
            }
        }
    }
    

如果您需要一些重型验证,则可以为emailValid制作隐藏的Mutable字段并在后台验证完成时手动更新

相关内容

最新更新