从 Firestore 异步调用填充 RecyclerView

Posted

技术标签:

【中文标题】从 Firestore 异步调用填充 RecyclerView【英文标题】:Populate RecyclerView from Firestore async call 【发布时间】:2020-05-22 22:30:35 【问题描述】:

我能够从 Firestore 中检索数据(它在 populateValletList() 的 GlobalScope 中绝对可用,并且我能够从 asnyc 数据库调用或简单地将 Vallet 添加到我的项目列表中填充我的 RecyclerView手动在populateValletList() 中,但是,当我想从 Firestore 数据填充该视图时,它不起作用。

RecyclerAdapter 中的 onBindViewHolder 不再被调用

override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) 
    when(holder)
        is ValletViewHolder ->
            holder.bind(items[position])
        
    

这就是我填充我的项目 private var items : MutableList<Vallet> = ArrayList() 的方式:

fun populateValletList() 
    GlobalScope.launch 
        items = getAllValletsFromDatabase.executeUseCase()
    

我在 onActivityCreated 中初始化了我的 RecyclerView

private fun initRecyclerView()
    recycler_view_vallets.apply
        layoutManager = LinearLayoutManager(context)
        addItemDecoration(ValletRecyclerAdapter.ValletItemDecorator(30))
        valletAdapter = ValletRecyclerAdapter()
        adapter = walletAdapter
    
    valletAdapter.populateValletList()

这是我第一次使用协程,我在这里忽略了什么?

【问题讨论】:

【参考方案1】:

好的,我认为您可以在代码中进行一些改进,但我认为无法按您想要的方式工作的原因是因为我更新了您的项目列表,您必须调用 notifyDataSetChanged() 在您的适配器上。

理想情况下,您应该使用非全局范围运行您的协程,为避免泄漏,您可以为其使用视图模型,或者您可以在您的片段中使用 lifecycleScope.run ,例如我相信你需要添加一个依赖。

    implementation "androidx.lifecycle:lifecycle-extensions:2.2.0"

关于更新你的回收器,我推荐使用 ListAdapter,所以它添加了 DIFF Utils 并且更容易更新值。

总结一下。

你的 Recycler Adapter 应该是这样的:

class HomePatchesAdapter : ListAdapter<Vallet, RecyclerView.ViewHolder>(REPO_COMPARATOR) 


    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder 
        return HomePatchesViewHolder.create(parent, viewType)
    

    override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) 
        val repoItem = getItem(position)


        if (repoItem != null) 
            (holder as HomePatchesViewHolder).bind(repoItem)
        
    


    companion object 
        private val REPO_COMPARATOR = object : DiffUtil.ItemCallback<Vallet>() 
            override fun areItemsTheSame(oldItem: Vallet, newItem: Vallet): Boolean =
                oldItem.name == newItem.name

            override fun areContentsTheSame(oldItem: Vallet, newItem: Vallet): Boolean =
                oldItem == newItem
        
    



你的片段会是这样的:

private fun initRecyclerView()
    recycler_view_vallets.apply
        layoutManager = LinearLayoutManager(context)
        addItemDecoration(ValletRecyclerAdapter.ValletItemDecorator(30))
    

        val adapter = HomePatchesAdapter()
        recycler_view_vallets?.adapter = adapter

    lifecycleScope.run 

      adapter.submitList(getAllValletsFromDatabase.executeUseCase())

      


让我知道这是否有意义。

【讨论】:

我有几分钟的时间尝试 notifyDataSetChanged() 并且它成功了。稍后我会阅读您使用 ListAdapter 的建议,并在我有更多空闲时间时弄清楚它是如何工作的。 很高兴我能帮忙:)

以上是关于从 Firestore 异步调用填充 RecyclerView的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 Cordova 将动态数据从表单传递到 Firestore?

如何为从 Firestore 填充的 RecyclerView 实现过滤器?

如何在异步调用期间填充数组并将其发送到响应对象中

从 firebase firestore 参考中获取异步值

在 dart/flutter 中执行多次从 firestore 获取数据的异步函数

Firestore 的异步功能不会加载我的数据