My app is an app that gets data from Firebase, and then shows the data in RecyclerView.
I had a few problems and solved the problems by searching, but I have some questions.
First, here is my code.
val productList = mutableListOf<Product>()
database.get().addOnSuccessListener {
for (item in it.children) {
productList.add(Product(item.key.toString(), item.child("name").value.toString(), item.child("photo").value.toString(), item.child("content").value.toString(), decimal.format(item.child("price").value.toString().toInt()).toString() + " P", item.child("price").value.toString().toInt()))
}
binding.pointMallHomeRecyclerView.adapter?.notifyDataSetChanged() // THIS POINT IS THAT I'M CURIOUST ABOUT
}
val myDataset = productList
val adapter = PointMallMainItemAdapter(requireContext(), myDataset, object: PointMallMainItemAdapter.OnItemClickListener {
override fun onItemClick(v: View, position: Int, id: String, content: String, photo: String) {
val action = PointMallHomeFragmentDirections.actionPointMallHomeFragmentToPointMallItemFragment(productId = id, content = content, photo = photo)
findNavController().navigate(action)
}
})
binding.pointMallHomeRecyclerView.adapter = adapter
When I coded it first, there isn’t the
binding.pointMallHomeRecyclerView.adapter?.notifyDataSetChanged()
That way, there are data in the ‘productList’, but nothing appears in the RecyclerView.
But, after I added that code, it works. Why does it happen? Doesn’t the code work sequentially? Is it because connecting the adapter runs faster than getting data from the DB? If it works sequentially, if the app gets all the data, it connects the adapter, right?
2
Answers
There is nothing displayed in your RecyclerView because your
productList
is empty when you’re using:Why? Because the Firebase API is asynchronous. And it’s normal behavior since reading a list of objects takes time. The solution is simple and always the same, any code that needs data from a Firebase database needs to be inside the
onSuccess()
method, or be called from there. In your particular case, you have to move the above line of code right inside the callback:You might also be interested in reading my answer in the following post regarding the Realtime Database:
And another one regarding Firestore:
is, as the name mentions, responsible for notifying the adapter that new data has been introduced into the adapter.
Without this call the adapter will not be updated automatically.
Note, however, that this call recalculates ALL items in the adapter. This costs computing time.
If you are simply updating one or just a view parts of the list, use the
notifyItemRangeChanged(int start, int end)
ornotifyItemChanged(int position)
instead ofnotifiyDataSetChanged()
.More info can be found here: https://developer.android.com/reference/android/support/v7/widget/RecyclerView.Adapter.html#notifyItemRangeChanged(int,%20int)