android - ObservableField 值更改未传播

标签 android mvvm kotlin rx-java android-databinding

我是 mvvm 和 rxbinding 的新手。
我正在尝试使用 RxJava 和 DataBinding 将我的 ViewModel 与 android 上下文完全分离。

当我对 ViewModel 的某些代码(即表单验证)进行单元测试时,我的 ObservableFields 不会更改值并且该值保持为空。

我的 ViewModel 的最小示例:

class RegistrationViewModel(var validator: Validator) : ViewModel {

    val username: ObservableField<String> = ObservableField()
    val password: ObservableField<String> = ObservableField()

    var signInButtonEnabled: ObservableField<Boolean>
    var emailErrorVisibility: ObservableField<Boolean>

    private fun validatePassword(password: String?) = password?.trim()!!.length >= 6

    private fun validateUsername(username: String?) = validator.isValid(Validator.Field.EMAIL, username)

    init {
        val inputValid = Observable.combineLatest(
                toObservable(username),
                toObservable(password),
                BiFunction<String, String, Boolean> { t1, t2 ->
                    validateUsername(t1) && validatePassword(t2)
                }
        )

        signInButtonEnabled = toField(inputValid)
        emailErrorVisibility = toField(toObservable(username).map { t -> !validateUsername(t) })
    }
}

我希望只要 ObservableField 用户名的值发生更改,就会设置 ObservableField emailErrorVisibility

我的单元测试:
@Test
fun test_hideUsernameErrorMessage() {
        val validator = mock(RegistrationValidator::class.java)

        val viewModel = RegistrationViewModel(validator)

        viewModel.username.set("")
        assertThat(viewModel.emailErrorVisibility.get(), equalTo(false))

        val invalidValue = "ABC"
        Mockito.`when`(validator.isValid(Validator.Field.EMAIL, invalidValue)).thenReturn(false)
        viewModel.username.set(invalidValue)
        assertThat(viewModel.username.get(), equalTo(invalidValue))
        assertThat(viewModel.emailErrorVisibility.get(), equalTo(true))
}

viewModel.username.set("") 行之后在这个测试中 viewMode.emailErrorVisibility 的值仍然不是。

值应该通过更改/设置用户名值来更新自己,我错了吗?

注意,函数 toField(Observble) 来自 https://github.com/manas-chaudhari/android-mvvm/blob/master/android-mvvm/src/main/java/com/manaschaudhari/android_mvvm/FieldUtils.java

最佳答案

数据绑定(bind)在设置绑定(bind)值时尝试高效。更改值时,它会发布以确保您在设置所有值之前完成更改。如果您仍在进行更改,则无需评估更改。

您可以使用 executePendingBindings() 强制评估此类情况下的边界值。 :

    viewModel.username.set("")
    binding.executePendingBindings()
    assertThat(viewModel.emailErrorVisibility.get(), equalTo(false))

关于android - ObservableField 值更改未传播,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47138322/

相关文章:

java - setDisplayHomeAsUpEnabled 不显示带有自定义操作栏 View 的后退箭头

android - RemoteServiceException 在 MIUI 11 上使我的应用程序崩溃

kotlin - 在 Mac 上哪里可以找到(安装)Kotlin cinterop 工具

WPF 在同一窗口中更改数据上下文和 View

c# - 将命令参数传递给 WPF 中 ViewModel 中的方法?

c# - ViewModel 在发布时丢失数据

functional-programming - Kotlin减少了如何对多个元素进行操作

android - Scrollview 水平和垂直不能同时工作

android - 发送带有 URI 数据的 Android Beam

android - 重复条目 : com/google/android/gms/internal/zzahl. 类