Animate list items in ListView

14,172

Solution 1

If you use getView() simple code here, (No need custom library)

private int lastPosition = -1;

@Override
public View getView(int position, View convertView, ViewGroup parent) {
//Load your view, populate it, etc...
View view = ...;

Animation animation = AnimationUtils.loadAnimation(getContext(), (position > lastPosition) ? R.anim.up_from_bottom : R.anim.down_from_top);
view.startAnimation(animation);
lastPosition = position;

return view;
}

up_from_bottom.xml

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
 android:shareInterpolator="@android:anim/decelerate_interpolator">
<translate
    android:fromXDelta="0%" android:toXDelta="0%"
    android:fromYDelta="100%" android:toYDelta="0%"
    android:duration="400" />
</set>

down_from_bottom.xml

 <?xml version="1.0" encoding="utf-8"?>
 <set xmlns:android="http://schemas.android.com/apk/res/android"
 android:shareInterpolator="@android:anim/decelerate_interpolator">
<translate
    android:fromXDelta="0%" android:toXDelta="0%"
    android:fromYDelta="-100%" android:toYDelta="0%"
    android:duration="400" />
 </set>

Reference from this site:http://kylewbanks.com/blog/Implementing-Google-Plus-Style-ListView-Animations-on-Android

Solution 2

Animate each added element in the getView method of your Custom Adapter.

public View getView(int position, View convertView, ViewGroup parent) {

    View v = convertView;

    if (v == null) {
        LayoutInflater vi = (LayoutInflater) getActivity()
            .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        v = vi.inflate(R.layout.simple_list_item_1, null);
    }

    ListData o = list.get(position);
    TextView tt = (TextView) v.findViewById(R.id.toptext);

    tt.setText(o.content);

    Log.d("ListTest", "Position : "+position);

    if(flag == false) {
        Animation animation = AnimationUtils.loadAnimation(getActivity(), R.anim.slide_top_to_bottom);
        v.startAnimation(animation);
    }
    return v;
}

And thereby achieve the animation.

Solution 3

Have a look at the ListViewAnimations library to animate your ListView items.

Basically, you would only have to add two more lines to have your items animated:

Before:

MyListAdapter mAdapter = new MyListAdapter(this, getItems());
getListView().setAdapter(mAdapter);

After:

MyListAdapter mAdapter = new MyListAdapter(this, getItems());
AlphaInAnimationAdapter alphaInAnimationAdapter = new AlphaInAnimationAdapter(mAdapter);
alphaInAnimationAdapter.setAbsListView(getListView());
getListView().setAdapter(alphaInAnimationAdapter);

Solution 4

I had a similar problem. I'm not 100% sure if this is the right way to go, but you can try clearing the animation on the view before starting a new one to cancel any leftover animation from the recycled view. This helped me.

if(flag == false) {
    v.clearAnimation();
    Animation animation = AnimationUtils.loadAnimation(getActivity(), R.anim.slide_top_to_bottom);
    v.startAnimation(animation);
}
Share:
14,172
Mate Gulyas
Author by

Mate Gulyas

Updated on June 09, 2022

Comments

  • Mate Gulyas
    Mate Gulyas almost 2 years

    I try to animate new items in my ListView. I have stable id-s, so I know exactly which element to animate. The problem comes from the recycle mechanism of ListView. I call startAnimation on the View when I know I got a recently inserted element. But then, the view got recycled, filled with different data. It results on the UI animating the wrong row. At some point the view was holding the right data, but then got recycled. I confirmed this via logcat. Is there any way to solve this?

    EDIT:

    public ExpensCursorAdapter(Context context, Cursor c, boolean autoRequery,
            CopyOnWriteArraySet<String> fadeAnimateTags) {
        super(context, c, autoRequery);
        this.mFadeAnimTags = fadeAnimateTags;
    }
    
    @Override
    public boolean hasStableIds() {
        return true;
    }
    
    @Override
    public void bindView(View view, Context context, Cursor cursor) {
        setup(view, context, cursor);
    }
    
    private void setup(View view, Context context, Cursor cursor) {
        final String id = cursor.getString(4);
        if (LOCAL_LOGV) Log.v(TAG, String.format("Create item for %s. Received view: %s", id, view.toString()));
        view.setTag(id);
        final TextView dateText = (TextView) view.findViewById(R.id.date);
        final TextView timeText = (TextView) view.findViewById(R.id.time);
        final TextView title = (TextView) view.findViewById(R.id.title);
        final TextView amount = (TextView) view.findViewById(R.id.amount);
        final Date date = new Date(cursor.getLong(0));
        title.setText(cursor.getString(1));
        dateText.setText(dFormat.format(date));
        timeText.setText(tFormat.format(date));
        amount.setText(String.format("%d Ft", cursor.getInt(2)));
        if (cursor.getInt(3) == 1) {
            timeText.setTextColor(Color.LTGRAY);
            title.setTextColor(Color.LTGRAY);
            dateText.setTextColor(Color.LTGRAY);
            amount.setTextColor(Color.LTGRAY);
        } else {
            timeText.setTextColor(Color.BLACK);
            title.setTextColor(Color.BLACK);
            dateText.setTextColor(Color.BLACK);
            amount.setTextColor(Color.BLACK);
        }
        if (mFadeAnimTags.contains(id)) {
         view.setAnimation(AnimationUtils.loadAnimation(context, R.anim.fade));
         mFadeAnimTags.remove(id);
        }
    
    }
    
    @Override
    public View newView(Context context, Cursor cursor, ViewGroup parent) {
        final LayoutInflater inflater = LayoutInflater.from(context);
        View view = inflater.inflate(R.layout.expense_list_item, parent, false);
        setup(view, context, cursor);
        return view;
    }
    
  • Korniltsev Anatoly
    Korniltsev Anatoly about 11 years
    don't ever animate in adapter
  • Jorge Gil
    Jorge Gil almost 11 years
    @KorniltsevAnatoly so where and how?
  • Yasitha Waduge
    Yasitha Waduge over 10 years
    +1 Really nice library. Small concern, once listview loaded, I need to add additional items to listview, when adding additional items, I need those items to be animated(animate only newly added items while adding), does that support in this library?