【问题标题】:Populate RecyclerView from Firestore async call从 Firestore 异步调用填充 RecyclerView
【发布时间】: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()
}

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

【问题讨论】:

    标签: android firebase kotlin google-cloud-firestore coroutine


    【解决方案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 的建议,并在我有更多空闲时间时弄清楚它是如何工作的。
    • 很高兴我能帮忙:)
    猜你喜欢
    • 2023-01-11
    • 2019-04-30
    • 2018-08-11
    • 1970-01-01
    • 2018-09-20
    • 2019-06-19
    • 2018-09-22
    • 2017-07-26
    • 1970-01-01
    相关资源
    最近更新 更多