Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

NotifyDataSetChanged caused recycleview to blink #232

Closed
taingmeng opened this issue Apr 20, 2016 · 9 comments
Closed

NotifyDataSetChanged caused recycleview to blink #232

taingmeng opened this issue Apr 20, 2016 · 9 comments
Labels

Comments

@taingmeng
Copy link

When there are items in recycleview, and I pull to refresh to get updated items from server, pass them into adapter and call notifyDataSetChanged in the adapter. It caused the recycleview to blink. The adapter here is the original adapter, not the wrapped adapter. Am I updating wrong adapter or is there any addition all steps to avoid the blink?

@h6ah4i
Copy link
Owner

h6ah4i commented Apr 20, 2016

Hi. Maybe, setSupportsChangeAnimations(false) will solve the problem.

((DefaultItemAnimator) recyclerView.getItemAnimator()).setSupportsChangeAnimations(false);

ref.) SimpleItemAnimator.html#setSupportsChangeAnimations(boolean)

Or if you want to finish all other animations (move, add or delete) immediately, try the following code.

recyclerView.getItemAnimator().endAnimations();

@taingmeng
Copy link
Author

Thank you for your swift reply. I have found the reason. The fault is on my side where I always return different long id in getItemId(int position) in the adapter when I do refresh.

@h6ah4i
Copy link
Owner

h6ah4i commented Apr 21, 2016

Yes, that is the correct solution. Using not consisted ID value causes such unwanted item animations.

@h6ah4i h6ah4i closed this as completed Apr 21, 2016
@bhargavbvs
Copy link

Hi, I implemented the moveitem in draggable grid layout and this causes for bad animation. It is going back to the same position and after moving and then the data changes. How to solve this!!

@taingmeng
Copy link
Author

Did you override getItemId correctly? If you have duplicate ids, your app might crash or views will return back to the same position.

@Override
public long getItemId(int position) {
        //return unique id for each view
 }

@bhargavbvs
Copy link

bhargavbvs commented Oct 26, 2016

@Override
    public long getItemId(int position) {
        return position;
    }

Yes, I have done that! I have implemented my own moveItem as he uses the AbstractDataProvider

private void moveItem(int fromPosition, int toPosition){
        final String item = strings.remove(fromPosition);
        strings.add(toPosition, item);
    }

The items are list of strings so in order to move I am using this method. Thanks!!

@taingmeng
Copy link
Author

By returning the position as id, I don't think it will work as you expected. Usually I return the unique attribute of the item at that position, for example,

@Override
public long getItemId(int position) {
    return items.get(position).getId();
}

In your case, if each string in strings is unique, you can try:

@Override
public long getItemId(int position) {
    return strings.get(position).hashCode();
}

It is not a fool-proof solution, but it should work.

@bhargavbvs
Copy link

Cool, struggling to find what went wrong. Thanks for your time man! This should be properly documented in the library that the unique attribute should be given.

@taingmeng
Copy link
Author

If you encounter blinking as I did, make sure the id you return is unique and does not change when you move view or at any point of time.

If you use strings.get(position).hashCode() as I suggested, and any string in strings is changed, it might cause blinking.

joshfriend added a commit to joshfriend/android-advancedrecyclerview that referenced this issue Jun 8, 2017
h6ah4i added a commit that referenced this issue Sep 18, 2017
…pter (#400)

*IMPORTANT*
A new callback method have been added to SwipeableItemAdapter.
So please add this new onItemSwipeStarted() method to your adapter.

Inside the method, you can call notify*() method to invalidate items.
Before this change, the library always calls the notifyDataSetChanged()
method internally. If you need the same behavior, put a method call
of notifyDataSetChanged() in the onItemSwipeStarted().

Related issues/pull requests
- Only notify adapter to change the item being swiped #395
- NotifyDataSetChanged caused recycleview to blink #232
- swipe not so smooth like examples #129
h6ah4i added a commit that referenced this issue Oct 9, 2017
…pter (#400)

*IMPORTANT*
A new callback method have been added to SwipeableItemAdapter.
So please add this new onItemSwipeStarted() method to your adapter.

Inside the method, you can call notify*() method to invalidate items.
Before this change, the library always calls the notifyDataSetChanged()
method internally. If you need the same behavior, put a method call
of notifyDataSetChanged() in the onItemSwipeStarted().

Related issues/pull requests
- Only notify adapter to change the item being swiped #395
- NotifyDataSetChanged caused recycleview to blink #232
- swipe not so smooth like examples #129
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

3 participants