值更新时不调用 Android BindingAdapter

And*_*Dev 1 android android-databinding android-livedata

Activity、二Fragment有共同点ViewModel。我已经验证每个片段中的视图模型引用都是相同的。

在片段一的布局 XML 中,有一个TextInputLayout. 片段二用布尔值更新视图模型。文本输入布局正在观察该值,并且应该BindingAdapter在该值更改时调用 a 。

当片段实例化并且它们的布局膨胀时,绑定适配器会触发,所以我知道视图正在观察这个值。但是,稍后,当片段二更新值时,片段一中的视图不会触发绑定适配器。

这是onCreateView()片段一中的内容:

registrationViewModel = activity?.run {
            ViewModelProviders
                .of(this, RegistrationViewModelFactory(prefs, dataFetcherService))
                .get(RegistrationViewModel::class.java)
        } ?: throw Exception("Invalid Activity")
Run Code Online (Sandbox Code Playgroud)

这是观察该视图模型的视图:

    <com.google.android.material.textfield.TextInputLayout
                android:id="@+id/reg_auth_code_layout"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
bind:errorState="@{registrationViewModel.registrationData.authorizationError}"
                bind:errorMessage="@{@string/invalid_auth_code}">

                <com.google.android.material.textfield.TextInputEditText
                    android:id="@+id/reg_auth_code"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:text="@{registrationViewModel.registrationData.authCode}"
                    android:hint="@string/enter_auth_code"
                    android:maxLines="1"
                    android:inputType="text"
                    android:imeOptions="actionDone"
                    app:autoSizeTextType="uniform"/>

            </com.google.android.material.textfield.TextInputLayout>
Run Code Online (Sandbox Code Playgroud)

至于片段二,onCreateView() 中的代码相同:

registrationViewModel = activity?.run {
            ViewModelProviders
                .of(this, RegistrationViewModelFactory(prefs, dataFetcherService))
                .get(RegistrationViewModel::class.java)
        } ?: throw Exception("Invalid Activity")
Run Code Online (Sandbox Code Playgroud)

单击按钮时,片段二会在视图模型中触发一个活动:

private fun attemptNavigationToUserData() {
    viewModelScope.launch {
        isAuthorized = runBlocking { useCase.isAuthorized() }
        registrationData.value?.authorizationError = !isAuthorized
    }
}
Run Code Online (Sandbox Code Playgroud)

最后,这是 BindingAdapter:

@BindingAdapter("errorState", "errorMessage")
fun setErrorState(
    textInputLayout: TextInputLayout?,
    errorState: Boolean,
    errorMessage: String) {

    textInputLayout?.let {
        it.isErrorEnabled = errorState
        if (errorState) it.error = errorMessage
    }
}
Run Code Online (Sandbox Code Playgroud)

AFAIK,这一切似乎都设置正确。正如我所提到的,绑定适配器在视图最初膨胀时触发,但再也不会触发。

为什么我的 XML 没有观察到视图模型?或者,为什么绑定适配器在更新时不触发?

谢谢你的帮助。

小智 7

答案很可能是您没有为片段绑定对象设置生命周期Owner。有关更多信息,请参阅/sf/answers/3920825891/