Animate ListView items on notifyDataSetChanged()
Solution 1
There are many ways to achieve this, you can try the answers in this question :
How to Animate Addition or Removal of Android ListView Rows
The 1st answer is working
Solution 2
No, at least I haven't found that Android can report to me if there are new or deleted items. I made something similar where the items of the ListView animate to their new positions and I had to track their positions myself to do that.
For your use case, it is probably easier to put the fading animation just before you delete the row from the database. So wherever in your code it is that you delete the row from the database and trigger a refresh, you do the fade animation on the item and on completion of the animation you delete the row and trigger a refresh.
Update
Hmmm, I read too quickly. Your example is not a fade-out on deleted items, but a fade-in on new items.
You will have to track item IDs yourself in your adapter. This approach can only work if you have a limited number of items to show because the list of previous item IDs will have to be stored in memory. If you can not be certain the list is never too large then you'll have to find a way to add the 'newness' information to the cursor itself.
Let me see if I can cook something up. Be back later...
Update 2
Below is a SimpleCursorAdapter that keeps track of the item ID from the previous cursor. In getView()
it kicks of the fade-in animation if the requested view is for an item that was not present before.
private static class FadeInAdapter extends SimpleCursorAdapter {
private List<Long> previousItemIds = new ArrayList<Long>();
private FadeInAdapter(Context context, int layout, Cursor c, String[] from, int[] to, int flags) {
super(context, layout, c, from, to, flags);
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
View result = super.getView(position, convertView, parent);
// check if this view is for an item that is new
long itemId = getItemId(position);
if (!previousItemIds.contains(itemId)) {
// do the fade-in animation
result.setAlpha(0);
result.animate().alpha(1).setDuration(500).start();
}
return result;
}
@Override
public void changeCursor(Cursor cursor) {
Cursor oldCursor = getCursor();
if (oldCursor != null) {
// store previous item IDs to check against for newness with the new cursor
final int idColumnIndex = oldCursor.getColumnIndexOrThrow(DatabaseContract._ID);
previousItemIds.clear();
for (oldCursor.moveToFirst(); !oldCursor.isAfterLast(); oldCursor.moveToNext()) {
previousItemIds.add(oldCursor.getLong(idColumnIndex));
}
}
super.changeCursor(cursor);
}
}
sagus_helgy
Updated on July 26, 2022Comments
-
sagus_helgy over 1 year
I want to add some animation to my
ListView
withSimpleCursorAdapter
when my DB data changes. I am usingSimpleCursorAdapter
withLoaderManager
I tried to add animation ingetView
method@Override public View getView(int position, View convertView, ViewGroup parent) { View view=super.getView(position, convertView, parent); //My animation(nineoldandroid) ObjectAnimator.ofFloat(view,"alpha",0,1).setDuration(500).start(); return view; }
But this method animates all items, although some items were the same before updating. Does Android have methods to detect which items need update, remove or add?
For example, maybe there are methods for getting changes between old and new cursor before calling
myAdapter.swapCursor(newCursor);
It would be possible to mark items(removed, updated, new) and make removing animation before swapping and ither animation ingetView
. How can I solve this problem? -
sagus_helgy over 9 yearsThe point of question is how to set different animation for different changes.
-
antonio081014 over 7 yearsBased on answer from the link, I think you could apply different animation to different row items based on the index. @Sufferer