marcorei / Infinite-Fire

Connects Firebase to a RecyclerView
Apache License 2.0
19 stars 7 forks source link

Strange behavior/animation when adding/Removing items #9

Open tamimattafi opened 6 years ago

tamimattafi commented 6 years ago

i am trying to create a chat activity so that users can send messages to each other.. i'm using Firebase Database in this case, with marcorei/Infinite-Fire as an Adapter.. The problem is when ever the user sends/receives a message, the RecyclerView starts blinking and doing some other strange behaviors.. but that only happens when there are only few items.. after that everything gets perfect. well , i'm also using FirebaseDatabase.getInstance().setPersistenceEnabled(true); so the user can access his data even if he's offline. i think that the problem is when the user clicks send.. the message is pending/stored in the app cash and in few moments it will be stored to the Database , when this happens.. the RecyclerView refresh the last item.

Note : I Uploaded a short video to YouTube , so it can describe the issue more efficiently. Click Here To Watch The Video an other type is shown here Click Here

i tried a lot of codes but none have worked/was enough.. so here's what i did,

1- Setting item animator to null :

mRecyclerView.setItemAnimator(null);

2- Setting Supports Change animation to false :

RecyclerView.ItemAnimator animator = mRecyclerView.getItemAnimator();
    if (animator instanceof SimpleItemAnimator) {
        ((SimpleItemAnimator) animator).setSupportsChangeAnimations(false);
    }

3- Setting Add/Remove duration to 0 :

mRecyclerView.getItemAnimator().setAddDuration(0);
mRecyclerView.getItemAnimator().setRemoveDuration(0);

4- Setting stable IDs for the adapter to true : but that prevents the adapter to show more items , it only updates the last item to the newest added one.

adapter.setHasStableIds(true);

Here is my code :

marcorei commented 6 years ago

This looks strange. I guess this is caused by events fired by Firebase. messageTime looks like it's a server-generated timestamp which would cause Firebase to update the message soon after you created it.

I'd suggest copying the InfiniteFireRecyclerViewAdapter and logging the onChanged events to see if they correlate with the blinking.

tamimattafi commented 6 years ago

@marcorei That's correct, messageTime is a server-generated timestamp and I've mentioned that firebase might update the message soon after i create it

" i think that the problem is when the user clicks send.. the message is pending/stored in the app cash and in few moments it will be stored to the Database , when this happens.. the RecyclerView refresh the last item. "

i need the timestamp to show the users message time depending on each one's time zone.. using system time might cause a serious problem with that. don't you think i should disable case Changed: notifyItemChanged(index + indexOffset); break; ?? so the RecyclerView won't update that specific message. I'm also curious about why this happen only to the first 10-15 items then it becomes normal?

marcorei commented 6 years ago

No idea why the behavior changes after 10-15 items. The events fired by Firebase change after the total number of items exceed the limit of the query, but your initial page size is 50 so that shouldn't be an issue.

Based on your videos and the fact that the problem still exists even if you remove the ItemAnimator my guess would be that Firebase removes the new item and adds it again.

Can you reproduce the issue in a simple setup, for example with the example app in this repository?

(I agree that you should always use the server generated timestamp)