2019 年 11 月更新 - 它现在在最新版本上按预期工作。
原帖:
我正在通过公开公开的函数 setRefreshing(应用程序:XML 中的刷新)将 MutableLiveData 绑定到我的 SwipeRefreshLayout 并且当时一切正常......但是让我们介绍一下我的应用程序架构。
当我根据刷新状态更改其值时,我有带有 MutableLiveData 的抽象 ViewModel。
然后我有两个从这个抽象继承的 ViewModel(让我将它们命名为 FirstViewModel 和 SecondViewModel),命名为 BaseRefreshViewModel。首先,我有两个几乎相同的 XML 文件,仅在第一个 XML 中导入 FirstViewModel 和第二个 - 对应的 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
没有狗屎夏洛克...有趣的是,当我将 XML 文件中的导入从 BaseRefreshViewModel 更改为 FirstViewModel/SecondViewModel 时,即使没有我的 BindingAdapter,它也开始编译得很好(我当然不能这样,因为我有一个不同的列表我绑定到我的适配器的 ViewModels 中的对象)。
这是我在片段中的 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 及其生命周期优势。它只是显示了我认为现在数据绑定编译器是如何被窃听的。
概括:
WORKING(两个不同的xml,几乎一样)
- BaseRefreshViewModel (isRefreshing: MutableLiveData)
- 第一视图模型
- first_list_layout.xml(导入 FirstViewModel)
- 第二视图模型
- second_list_layout.xml(导入 SecondViewModel)
- 第一视图模型
工作(一个 xml 文件,但不是 LiveData)
- BaseRefreshViewModel (isRefreshing: ObservableBoolean)
- 第一视图模型
- list_layout.xml(导入 BaseRefreshViewModel)
- 第二视图模型
- list_layout.xml(导入 BaseRefreshViewModel)
- 第一视图模型
不工作(一个带有 LiveData 的 xml 文件)
- BaseRefreshViewModel (isRefreshing: MutableLiveData)
- 第一视图模型
- list_layout.xml(导入 BaseRefreshViewModel)
- 第二视图模型
- list_layout.xml(导入 BaseRefreshViewModel)
- 第一视图模型