Animate ListView items in notifyDataSetChanged ()

I want to add some animation to my ListView using SimpleCursorAdapter when changing database data. I am using SimpleCursorAdapter with LoaderManager I tried to add animation to the getView 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 the elements, although some elements were the same before the update. Does Android have methods to determine which items need to be updated, deleted or added?

For example, there may be ways to get changes between the old and the new cursor before calling myAdapter.swapCursor(newCursor); It would be possible to mark the elements (deleted, updated, new) and do the removal of the animation before replacing and animating ither in getView , How can I solve this problem?

+6
source share
3 answers

There are many ways to achieve this, you can try the answers in this question:

How to animate the addition or removal of Android ListView rows

First answer works

+1
source

No, at least I have not found that Android can tell me if there are any new or deleted items. I did something similar when ListView elements are expecting their new positions, and I have to track their positions myself.

For your use case, it's probably easier to put a fade animation just before deleting a row from the database. Therefore, wherever you are in your code, you delete the row from the database and start the update, you make a fade animation on the element, and when the animation finishes, you delete the row and start the update.

Update

Hmmm, I read too fast. Your example is not the gradual disappearance of deleted elements, but the damping of new elements.

You will need to track the identifiers of the elements yourself in your adapter. This approach can only work if you have a limited number of items to display, because the list of previous item IDs needs to be kept in memory. If you cannot be sure that the list is never too long, you will need to find a way to add โ€œnoveltyโ€ information to the cursor itself.

Let me see if I can cook anything. Come back later ...

Update 2

The following is a SimpleCursorAdapter that tracks the identifier of an element from a previous cursor. In getView() it starts a fade animation if the requested view refers to an element that was not previously present.

 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); } } 
+1
source

Maybe RecyclerView helps. Try notifyItemChanged

0
source

Source: https://habr.com/ru/post/978016/


All Articles