android - 如何使用 fragment 内的实时数据更新 Recycler View ?

标签 android android-recyclerview android-livedata androidx

我想更新我的回收器 View ,这样每当我从数据库中的表中删除一行时,它都会立即更新回收器 View 而不刷新 fragment 。

 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() 。我应该在代码中实现哪些更改?

最佳答案

我试图在 Internet 上找到一些示例解决方案。应该有,但是没找到。我发现其中许多太短或太详细。所以我会放在这里正是你需要的。有一个标准化的模式涉及 RecyclerView + LiveData , 所以你所有的 RecyclerView 都遵循这个模式+ LiveData用法。

fragment :

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应该实现 .submitList() View 将使用的函数
    class MyAdapter: RecyclerView.Adapter<ViewHolder>() {
    
        val myData = mutableListOf<Data>()
    
        fun submitList(newData: List<Data>) {
            myData.clear()
            myData.addAll(newData)
            notifyDataSetChanged()
        }
    }
    

    请注意 notifyDataSetChanged()是一个实际上向适配器发出更新 View 的信号。

    改进:

    我认为上述解决方案足以解决您的问题,因为您的列表不是太大或更新太频繁。如果您想进一步提高性能和/或可读性,请探索以下内容:
  • 使用Paging库对长列表或无限列表进行分页。
  • 按照评论中的建议,使用 DiffUtil 在工作线程中进行区分。
  • Binding图书馆减少一些样板
  • 关于android - 如何使用 fragment 内的实时数据更新 Recycler View ?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56528644/

    相关文章:

    android - 编译时由 : android. database.sqlite.SQLiteException : near "org": syntax error (code 1): , 引起:

    android - 如何使用 ItemTouchHelper 和光标实现拖放

    java - 我如何从 boyh recyclerview 和存储 android studio 中删除项目

    android - TextView 在某些分辨率下被删减

    android - 如何创建类似于附件图像的用户界面?

    android - Dagger @ContributesAndroidInjector ComponentProcessor 无法处理这个接口(interface)

    android - Android:为什么在尝试分配给变量时不运行Transformation.map?

    android - LiveData “pass-by-reference”初始值

    android - 无法解析 : androidx. 生命周期 :lifecycle-extensions-ktx:2. 0.0-alpha1

    android - 下载完成时收到消息