Animate ListView items on notifyDataSetChanged()
Asked Answered
B

3

7

I want to add some animation to my ListView with SimpleCursorAdapter when my DB data changes. I am using SimpleCursorAdapter with LoaderManager I tried to add animation in 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 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 in getView. How can I solve this problem?

Bronze answered 11/11, 2014 at 8:27 Comment(0)
I
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

Insecure answered 11/11, 2014 at 8:34 Comment(2)
The point of question is how to set different animation for different changes.Bronze
Based on answer from the link, I think you could apply different animation to different row items based on the index. @SuffererDecompound
U
1

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);
    }
}
Usherette answered 11/11, 2014 at 9:54 Comment(0)
B
0

Maybe RecyclerView helps. Try notifyItemChanged

Bremsstrahlung answered 18/8, 2017 at 9:4 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.