【问题标题】:Why does recyclerview adapter often changes from livedata observer even though no changes are there?为什么即使没有更改,recyclerview 适配器也经常从 livedata 观察者更改?
【发布时间】:2021-03-02 17:27:55
【问题描述】:

我有 2 个片段和一个活动。 Fragment A 和 Fragment B。我做了一些任务,然后如果我从 FragmentA 移动到 FragmentB 并按返回按钮返回。在这种情况下,状态不会像以前一样保持不变,而是像第一次一样获得新的视图。为什么?

实际上,我有一个recyclerview 和自定义工具栏。如果我滚动某个项目然后移动到fragment B 并返回,我应该处于相同的状态。

请注意:这个问题可能会被问很多次,但我的编码场景不同。

我正在使用 dagger hilt、kotlin、corutine、viewmodel、live data、recyclerview asynclist different 和 nav 组件。

代码: 片段A

 private val viewModel: ProductViewModel by viewModels<ProductViewModel>()
  • onviewcreated

    viewModel.getProducts.observe(viewLifecycleOwner, Observer { 响应 -> 停止微光布局() response.let { productResponse -> productAdapter.differ.submitList(productResponse) } setActionListener() })

ViewModel 类

class ProductViewModel @ViewModelInject constructor(
    private val repository: ProductRepository,
) : ViewModel() {

    val getProducts = liveData(Dispatchers.IO) {
        emit(repository.getProducts())
    }
}

【问题讨论】:

    标签: android kotlin


    【解决方案1】:

    LiveData 将始终在再次加载视图时为您提供其当前值。如果您不想要,那么我建议您转到 Kotlin FlowMutableStateFlow

    更新

    如果您更新了您的适配器数据(或存储库),当您的按钮发生变化时您应该这样做,然后再次调用 getProducts 以触发 livedata 观察者更新您的 recyclerview,您应该在返回时获取数据。

    这是我如何做的一个例子

    例子:

    视图模型

    class ProductViewModel @ViewModelInject constructor(
        private val repository: ProductRepository,
    ) : ViewModel() {
    
        val productsLiveData: MutableLiveData<Products> = MutableLiveData<Products>()
    
        fun getProductsAsync() {
            val data = repository.getProducts()
            productsLiveData.postValue(data)
        }
    
        fun updateDataAsync(){
            //Update your repository data
            //Call get products again to propagate the data change to the productsLiveData and recycler view
            getProductsAsync()
        }
    }
    

    片段

    override fun onViewCreated(view: View, savedInstanceState: Bundle?){
        viewModel.productsLiveData.observe(viewLifecycleOwner, Observer{
            //Update recycler view adapter here
            //Anytime you either call getProductsAsync() or updateDataAsync() from your viewmodel this will get called and you should update the adapter
            productAdapter.differ.submitList(productResponse) { setActionListener() })
        }
        viewModel.getProductsAsync()
    }
    

    很明显,您需要更新代码以适应您所拥有的,但这是我会这样做的基本流程,这样每当您加载片段时,它总会有最新的正确数据

    【讨论】:

    • 没关系,但数据永远不会从 API 更改
    • API 是否改变并不重要,如果您让实时数据发出一些东西,那么当您在视图加载时再次开始观察它时,它总是会发出该值
    • 我不知道您想通过该视频向我展示什么,但您拥有的代码与视频中的不匹配
    • 我想像这样处理保存状态,github.com/codinginflow/ImageSearchApp/blob/…
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-10-23
    • 2012-05-29
    • 1970-01-01
    • 2021-10-26
    • 1970-01-01
    • 2021-04-08
    相关资源
    最近更新 更多