英文:
Clear values inside of the MutableLiveData response collection
问题
我有一个应用程序,它使用API调用从服务器通过Retrofit
获取一些数据。我已经实现了SwiperRefreshLayout
以允许用户执行另一个调用。
目前,我在清除存储来自服务器的响应的MutableLiveData
集合方面遇到了困难。我希望每次触发OnRefreshListener
时都能清除该集合。
我尝试将MutableLiveData
“填充”为null
(因为它默认为空,对吗?),但由于我在OnCreateView
中设置了可观察对象以将数据传递给适配器,在每次刷新后我都会收到NullPointerException
错误。
我该如何解决这个问题?当OnRefreshListener
被触发时,我是否应该执行类似取消观察和重新观察response
集合的操作?以下是一些代码:
ViewModel
var responseData = MutableLiveData<Model?>()
fun fetchData(baseCurrency: String, selectedCurrencies: String) {
viewModelScope.launch {
val response =
retrofitRepository.fetchHistoricalData(date, selectedCurrencies, baseCurrency)
response.enqueue(object : retrofit2.Callback<Model> {
override fun onResponse(
call: Call<HistoricalRatesModel>,
response: Response<HistoricalRatesModel>
) {
if (response.isSuccessful) {
responseData.value = response.body()
}
}
override fun onFailure(call: Call<HistoricalRatesModel>, t: Throwable) {
Log.i(TAG, "onFailure ERROR\n${t.message}")
}
})
}
}
Fragment
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View {
_binding = FragmentHistoricalRatesBinding.inflate(inflater, container, false)
val view = mBinding.root
mViewModel.responseData.observe(requireActivity(), androidx.lifecycle.Observer {
mAdapter = Adapter()
mAdapter?.setData(it!!.rates)
mBinding.hrv.layoutManager = LinearLayoutManager(this.context)
mBinding.hrv.adapter = mAdapter
})
mBinding.refreshContainer.setOnRefreshListener {
// 在这里执行刷新操作
mBinding.refreshContainer.isRefreshing = false
}
return view
}
}
希望这可以帮助你解决问题。
英文:
I have an app, which uses api calls, to get some data by Retrofit
from the server. I've implemented SwiperRefreshLayout
to allow user, to perform another call.
Currently, I'm struggling with clearing MutableLiveData
collection, which stores response from the server. I'd like to clear that collection every time the OnRefreshListener
will be triggered.
I've tried to "fill" the MutableLiveData
with null
(as it comes by default, right?) but since I've set the observable in OnCreateView
to pass the data to the Adapter
, after every refresh I got NullPointerException
error.
How I may solve it? Should I do something like unobserving, and observing the response
collection again, when OnRefreshListener
is triggered? Here's some code:
ViewModel
var responseData = MutableLiveData<Model?>()
fun fetchData(baseCurrency: String, selectedCurrencies: String) {
viewModelScope.launch {
val response =
retrofitRepository.fetchHistoricalData(date, selectedCurrencies, baseCurrency)
response.enqueue(object : retrofit2.Callback<Model> {
override fun onResponse(
call: Call<HistoricalRatesModel>,
response: Response<HistoricalRatesModel>
) {
if (response.isSuccessful) {
responseData.value = response.body()
}
}
override fun onFailure(call: Call<HistoricalRatesModel>, t: Throwable) {
Log.i(TAG, "onFailure ERROR\n${t.message}")
}
})
}
}
Fragment
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View {
_binding = FragmentHistoricalRatesBinding.inflate(inflater, container, false)
val view = mBinding.root
mViewModel.responseData.observe(requireActivity(), androidx.lifecycle.Observer {
mAdapter = Adapter()
mAdapter?.setData(it!!.rates)
mBinding.hrv.layoutManager = LinearLayoutManager(this.context)
mBinding.hrv.adapter = mAdapter
})
mBinding.refreshContainer.setOnRefreshListener {
mBinding.refreshContainer.isRefreshing = false
}
return view
}
答案1
得分: 1
您没有处理潜在的 null 值,实际上您告诉编译器它永远不会为 null!
mViewModel.responseData.observe(requireActivity(), androidx.lifecycle.Observer {
...
mAdapter?.setData(it!!.rates)
})
您处理它的方式取决于当 null 值推送到观察者时您想要做什么。如果您想要清除适配器中的数据,您可以这样做:
mAdapter?.setData(it?.rates ?: emptyList<Rate>())
或者您可以使适配器的 setData()
函数接受 null(并在内部决定如何处理),然后您可以这样做:
mAdapter?.setData(it?.rates)
如果其中任何部分令您困惑,请确保您熟悉Kotlin中的空安全特性,以及thing?.stuff?.value
在链中的任何变量为 null 时会评估为 null。
英文:
You're not handling that potential null value in your observer - in fact you're telling the compiler that it will never be null!
mViewModel.responseData.observe(requireActivity(), androidx.lifecycle.Observer {
...
mAdapter?.setData(it!!.rates)
})
How you handle it depends on what you want to do when that null value is pushed to observers. If you want to clear the data in the adapter, you could do:
mAdapter?.setData(it?.rates ?: emptyList<Rate>())
or you could make your Adapter's setData()
function accept null (and decide internally how to handle that) and then you can just do:
mAdapter?.setData(it?.rates)
If any of that's confusing, make sure you're familiar with the null safety features in Kotlin, and how thing?.stuff?.value
evaluates to null if any of those variables in the chain are null
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论