清除MutableLiveData响应集合内的值

huangapple go评论43阅读模式
英文:

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&lt;Model?&gt;()



fun fetchData(baseCurrency: String, selectedCurrencies: String) {
    viewModelScope.launch {
        val response =
            retrofitRepository.fetchHistoricalData(date, selectedCurrencies, baseCurrency)
        response.enqueue(object : retrofit2.Callback&lt;Model&gt; {
            override fun onResponse(
                call: Call&lt;HistoricalRatesModel&gt;,
                response: Response&lt;HistoricalRatesModel&gt;
            ) {
                if (response.isSuccessful) {
                    responseData.value = response.body()
                }
            }

            override fun onFailure(call: Call&lt;HistoricalRatesModel&gt;, t: Throwable) {
                Log.i(TAG, &quot;onFailure ERROR\n${t.message}&quot;)
            }
        })
    }
}

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&lt;Rate&gt;())

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

huangapple
  • 本文由 发表于 2023年2月9日 03:17:24
  • 转载请务必保留本文链接:https://go.coder-hub.com/75390710.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定