Animate list items in ListView
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);
}
Mate Gulyas
Updated on June 09, 2022Comments
-
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 about 11 yearsdon't ever animate in adapter
-
Jorge Gil almost 11 years@KorniltsevAnatoly so where and how?
-
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?