问题
Basically, I have a RecyclerView with an adapter populating the data from a cursor. I have two options to get item animations:
Use
setHasStableIds(true)
and overridegetItemId
to return the ID of the database row, and then use aswapCursor
function in the adapter that swaps its current cursor with the new one and then callsnotifyDatasetChanged
Similar to option 1, but instead of simply swapping the cursor and calling
notifyDatasetChanged
, iterate over the old and new cursor, comparing the rows to determine which rows have been added/deleted/changed and keeping track of them, then callingnotifyItemAdded
,notifyItemChanged
, etc. to tell the adapter specifically what's been updated
With option 1, notifyDatasetChanged
will re-bind all the visible items (and some other stuff) which is inefficient, but with option 2 I would have to loop over the full cursor to figure out which items have been added/deleted, and if the cursor is fairly large, this could also take some time. Does anyone have any ideas about which would be the better solution and why?
Edit:
To make things even more interesting, I also have a third option:
- Similar to option 2, but instead of iterating over every item in the cursor, only iterate over the currently bound items (figured out by checking the
RecyclerView
's children) since the others will pick up the new cursor values when they're bound. The only problem with this is that it doesn't work for additions/deletions, so the way around it would be to do a full iteration ifoldCursor.count() != newCursor.count()
. If the counts are the same, I can dosetHasStableIds(false)
and then even if the row at a position is different than it was previously,onBindViewHolder
will take care of it.
Downsides of this would be that the ID's aren't stable, which means the RecyclerView
will have to do some extra work in some places
回答1:
Option 2 is prone to errors. I would go with option 1, keep it simple.
来源:https://stackoverflow.com/questions/35760310/which-is-more-expensive-notifydatasetchanged-or-looping-over-a-large-cursor