I want to update my Recycler View, so that whenever I delete a row from a table in a database, it updates the Recycler View at once without refreshing the 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
})
I believe I should not use the .observe() in the onCreateView() method. What changes should I implement in the code ??
I tried to find some example solutions on the Internet. There must be one, but couldn't find any. I find many of them are too short or too detailed. So I will drop here just exactly what you need. There is a standardized pattern involving RecyclerView
+ LiveData
, so just follow this pattern for all your RecyclerView
+ LiveData
usages.
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)
})
}
Few important changes made here:
.observe()
in onCreateView()
. Not just for this specific case, but in general you will never need to call .observe()
in any other places if you are using LiveData
correctly.viewLifecycleOwner
is the correct LifecycleOwner
to use for observing a LiveData
. (Unless you create a custom one.)RecyclerView
, even if your data changes over time. You should swap the data, not the whole adapter.MyAdapter:
MyAdapter
should implement the .submitList()
function that will be used by the view
class MyAdapter: RecyclerView.Adapter<ViewHolder>() {
val myData = mutableListOf<Data>()
fun submitList(newData: List<Data>) {
myData.clear()
myData.addAll(newData)
notifyDataSetChanged()
}
}
Note that notifyDataSetChanged()
is the one actually signals the adapter to update the view.
Improvements:
I think above solution is good enough for your problem, given that your list is not too big or too frequently updated. If you want further improvement in performance and/or readability, explore following: