如何使用片段中的实时数据更新Recycler视图?

时间:2019-06-10 14:47:28

标签: android android-recyclerview android-livedata androidx

我想更新我的Recycler View,以便每当我从数据库表中删除一行时,它都会立即更新Recycler View,而无需刷新片段。

 override fun onCreateView(
        inflater: LayoutInflater, container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View?
    {

        var binding:FragmentDisplayBinding = DataBindingUtil.inflate(inflater,R.layout.fragment_display,container,false)

        var view:View = binding.root

        var new_task : FloatingActionButton = view.findViewById(R.id.add_newTask)





        var db = Room.databaseBuilder(context!!,tasksDb:: class.java,"mydb").allowMainThreadQueries().build()
        viewManager = LinearLayoutManager(context)

        recyclerView = view.findViewById(R.id.recyclerView)

        db.task().getAll().observe(this, Observer {
            this.myAdapter = myAdapter(it)
            recyclerView.adapter = myAdapter
            recyclerView.layoutManager = viewManager
        })

我认为我不应该在onCreateView()方法中使用.observe()。我应该在代码中实现哪些更改?

2 个答案:

答案 0 :(得分:0)

可能会有所帮助。

要在回收站中刷新商品,您需要使用以下代码

myAdapter。 notifyDataSetChanged(); recyclerview.setAdapter(myAdapter);

对于您而言,在删除回收者视图项目的逻辑之后立即编写此方法。

答案 1 :(得分:0)

我试图在Internet上找到一些示例解决方案。必须有一个,但找不到。我发现其中许多内容太短或太详细。所以我将恰好放在您需要的地方。有一个涉及RecyclerView + LiveData的标准化模式,因此对于所有RecyclerView + LiveData的用法,请遵循此模式。

片段:

override fun onCreateView(
        inflater: LayoutInflater, container: ViewGroup?,
        savedInstanceState: Bundle?
): View? {

    ...

    val recyclerView = view.findViewById(R.id.recyclerView)
    val myAdapter = MyAdapter()
    recyclerView.adapter = myAdapter
    // recyclerView.layoutManager = LinearLayoutManager(context) // You need this only if you haven't set it in xml

    db.task().getAll().observe(viewLifecycleOwner, Observer {
        myAdapter.submitList(it)
    })
}

此处未进行一些重要更改:

  • 您必须在.observe()onCreateView()。不仅针对这种特定情况,而且如果正确使用.observe(),通常不需要在其他任何地方调用LiveData
  • viewLifecycleOwner是用于观察LifecycleOwner的正确LiveData。 (除非您创建一个自定义的。)
  • 取决于用例,但即使您的数据随时间变化,通常也会每个RecyclerView实例化一个适配器。您应该交换数据,而不是整个适配器。


MyAdapter:

MyAdapter应该实现视图将使用的.submitList()函数

class MyAdapter: RecyclerView.Adapter<ViewHolder>() {

    val myData = mutableListOf<Data>()

    fun submitList(newData: List<Data>) {
        myData.clear()
        myData.addAll(newData)
        notifyDataSetChanged()
    }
}

请注意,notifyDataSetChanged()实际上是向适配器发出信号以更新视图的信号。


改进之处

我认为上述解决方案足以解决您的问题,因为您的列表不是太大或更新得太频繁。如果您想进一步提高性能和/或可读性,请探索以下内容:

  • 使用Paging库对长列表或无限列表进行分页。
  • 按照注释中的建议使用DiffUtil在工作线程中进行区分。
  • Binding库以减少一些样板