'How to update Recyclerview new item added with smooth animation with firebase childEventListener?

I want to update recyclerview UI when new item added(chat item) with smooth animation. notifyDataSetChanged() casues whole list update glitchy animation.

I'm using to show chat item on recyclerview with firebase childEventListenior.

If I use notifyItemInserted() method which require position, how to get position inside onChildAdded() or onChildChanged() method ?

My code is below:

val childEventListener = object : ChildEventListener {
        override fun onChildAdded(dataSnapshot: DataSnapshot, previousChildName: String?) {
            Log.d("MESSAGE", "onChildAdded:" + dataSnapshot.key!!)
            val message = dataSnapshot.getValue(Message::class.java)
            messageList.add(message!!)
            messageAdapter!!.notifyDataSetChanged()
        }

        override fun onChildChanged(dataSnapshot: DataSnapshot, previousChildName: String?) {
            Log.d("MESSAGE", "onChildChanged: ${dataSnapshot.key}")
        }

        override fun onChildRemoved(dataSnapshot: DataSnapshot) {
            Log.d("MESSAGE", "onChildRemoved:" + dataSnapshot.key!!)
        }

        override fun onChildMoved(dataSnapshot: DataSnapshot, previousChildName: String?) {
            Log.d("MESSAGE", "onChildMoved:" + dataSnapshot.key!!)
        }

        override fun onCancelled(databaseError: DatabaseError) {
            Log.w("MESSAGE", "messages:onCancelled", databaseError.toException())
        }
    }
    messagesDatabaseRef.orderByChild("createdAt").addChildEventListener(childEventListener)
}


Solution 1:[1]

To get more granular updates (and animations) in a recycler view, you'll need to call the notifyItemInserted, notifyItemChanged, notifyItemMoved and notifyItemRemoved methods on the adapter, instead of notifyDataSetChanged. Calling these methods gives the adapter the information it needs for such updates.

As you noticed, you will need to specify positions to these calls, which means you will have to keep a mapping from the data/snapshots that you get from the database, to the position that they occupy in the view/adapter.

If you'd like to see an example of how to do this, have a look at the FirebaseRecyclerAdapter class in the FirebaseUI library, which does pretty much exactly that.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Frank van Puffelen