gpt4 book ai didi

android - 数据绑定(bind)和 MutableLiveData 的问题

转载 作者:行者123 更新时间:2023-12-05 00:16:38 28 4
gpt4 key购买 nike

2019 年 11 月更新 - 它现在在最新版本上按预期运行。

原帖:

我通过公开公开的函数 setRefreshing(XML 中的 app:refreshing)将 MutableLiveData 绑定(bind)到我的 SwipeRefreshLayout,到时候一切都正常......但是让我们介绍一下我的应用程序架构。

当我根据刷新状态更改其值时,我有带有 MutableLiveData 的抽象 ViewModel。

然后我有两个从这个抽象继承的 ViewModel(让我将它们命名为 FirstViewModel 和 SecondViewModel),将其命名为 BaseRefreshViewModel。首先,我有两个几乎相同的 XML 文件,仅当在第一个 XML 中导入 FirstViewModel 和在第二个 XML 中导入对应的 SecondViewModel 时,“数据”节点不同。

我太糟糕了,所以我将其合并到一个 XML 中并导入此 BaseRefreshViewModel (list_layout.xml):

<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">

<data>
<variable name="viewModel"
type="my.package.BaseRefreshViewModel" />
</data>

<androidx.coordinatorlayout.widget.CoordinatorLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/coordinator_layout">

<androidx.swiperefreshlayout.widget.SwipeRefreshLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
app:refreshing="@{viewModel.isRefreshing}"
android:id="@+id/swipe_layout">

<androidx.recyclerview.widget.RecyclerView
android:id="@+id/station_list"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:adapter="@{viewModel.stations}"/>

</androidx.swiperefreshlayout.widget.SwipeRefreshLayout>
</androidx.coordinatorlayout.widget.CoordinatorLayout>
</layout>

然后编译器开始变得疯狂 - 它说:

Cannot find a setter for <androidx.swiperefreshlayout.widget.SwipeRefreshLayout app:refreshing> that accepts parameter type 'androidx.lifecycle.MutableLiveData'

If a binding adapter provides the setter, check that the adapter is annotated correctly and that the parameter type matches.

好吧,所以我编写了自己的 BindingAdapter(当然更改为 SwipeRefreshLayout 中的 app:refresh):

@BindingAdapter("refresh")
fun setRefreshing(view: SwipeRefreshLayout, refreshing: Boolean) {
view.isRefreshing = refreshing
}

还是同样的问题,然后我将 BindingAdapter 更改为:

@BindingAdapter("refresh")
fun setRefreshing(view: SwipeRefreshLayout, refreshing: MutableLiveData<Boolean>) {
refreshing.value?.let { view.isRefreshing }
}

它开始编译,但运行后我的应用程序崩溃并出现错误:

Caused by: java.lang.ClassCastException: java.lang.Boolean cannot be cast to androidx.lifecycle.MutableLiveData

没有狗屎Sherlock...有趣的是,当我将XML文件中的导入从BaseRefreshViewModel更改为FirstViewModel/SecondViewModel时,即使没有我的BindingAdapter,它也开始编译得很好(我当然不能像这样离开它,因为我有ViewModel 中的不同对象列表,我将其绑定(bind)到我的适配器)。

这是我在 fragment 中的 ViewModel 初始化:

lateinit var stationViewModel: FirstViewModel

override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
stationViewModel = ViewModelProviders.of(requireActivity()).get(FirstViewModel::class.java)
}

override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
binding = DataBindingUtil.inflate(inflater, R.layout.list_layout, container, false)
binding.viewModel = stationViewModel
binding.lifecycleOwner = this
return binding.root
}

还有 ViewModel 本身:

abstract class BaseRefreshViewModel(application: Application) : AndroidViewModel(application) {

val isRefreshing = MutableLiveData<Boolean>().apply { value = false }


val receiver = object : StatusReceiver.Receiver {
override fun onReceiveResult(resultCode: Int, resultData: Bundle) {
when (resultCode) {
StatusReceiver.STATUS_RUNNING -> isRefreshing.value = true
StatusReceiver.STATUS_IDLE -> isRefreshing.value = false
StatusReceiver.STATUS_NO_CONNECTION -> isRefreshing.value = false
StatusReceiver.STATUS_ERROR -> isRefreshing.value = false
}
}
}

abstract fun refresh()

}

如何绕过这个问题,而不需要返回创建两个导入了不同 ViewModel 的 XML 文件?

我使用 Android Studio 3.5 Beta 5 只是为了利用 DataBinding 改进的错误消息。

更新:

当我将 MutableLiveData 更改为 ObservableBoolean() 时,它编译并运行良好...但我不想坚持这样做,我想使用 LiveData 及其生命周期优势。我认为它只是显示了数据绑定(bind)编译器现在是如何被窃听的。

摘要:

正在工作(两个不同的 xml,实际上相同)

  • BaseRefreshViewModel(正在刷新:MutableLiveData)
    • 第一个 View 模型
      • first_list_layout.xml(导入 FirstViewModel)
    • 第二个 View 模型
      • second_list_layout.xml(导入 SecondViewModel)

正在运行(一个 xml 文件,但不是 LiveData)

  • BaseRefreshViewModel(isRefreshing:ObservableBoolean)
    • 第一个 View 模型
      • list_layout.xml(导入 BaseRefreshViewModel)
    • 第二个 View 模型
      • list_layout.xml(导入 BaseRefreshViewModel)

不工作(一个包含 LiveData 的 xml 文件)

  • BaseRefreshViewModel(正在刷新:MutableLiveData)
    • 第一个 View 模型
      • list_layout.xml(导入 BaseRefreshViewModel)
    • 第二个 View 模型
      • list_layout.xml(导入 BaseRefreshViewModel)

最佳答案

应用插件后为我工作 kotlin-kapt在 kotlin 项目上

apply plugin: 'kotlin-kapt'

之后,LiveData<T>被展开为T当绑定(bind)到字段时。

根据记录,我还包含这些库

    // Lifecycle
implementation 'androidx.lifecycle:lifecycle-extensions:2.1.0'
implementation 'androidx.lifecycle:lifecycle-viewmodel-ktx:2.2.0-rc01'
implementation 'androidx.lifecycle:lifecycle-livedata-ktx:2.2.0-rc01'
implementation 'androidx.lifecycle:lifecycle-runtime-ktx:2.2.0-rc01'

关于android - 数据绑定(bind)和 MutableLiveData 的问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57051586/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com