14

How can I animate newly added items in ListView?

I have a adapter and when I add new items in my list I say adapter.notifyDataSetChanged(); the items are added, everything works perfectly, but my problem is I want newly added element to have some animation.

mavrosxristoforos
  • 3,573
  • 2
  • 25
  • 40
Lukap
  • 31,523
  • 64
  • 157
  • 244
  • I've got feeling that this is not an easy task. How many items are you planning to have in your `ListView`? – inazaruk Jun 07 '11 at 12:19
  • Well I want animation to be played every time when new item is added. There is something that changes my data randomly and adapter.notifyDataSetChanged(); i called every second, so if there is new data than it is presented on the listview that works perfectlly but problem is that there is no animation . . . – Lukap Jun 07 '11 at 12:29
  • The reason why I asked about the amount of items, is because you will have more chances to animate your additions to `LinearLayout`. But this is only feasible if you have fairly limited number of views. If you are planning to have say 50+ items in the list, then `LinearLayout` becomes way to expensive. – inazaruk Jun 07 '11 at 12:40
  • well having animated Linearlayout is nice if it is possible, I mean linear layout inside listview as item. Do you know how can I do that ? – Lukap Jun 07 '11 at 14:02
  • No, I meant `LinearLayout` **instead of** `ListView`. – inazaruk Jun 07 '11 at 14:06

3 Answers3

25

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.

mavrosxristoforos
  • 3,573
  • 2
  • 25
  • 40
ASH
  • 2,748
  • 2
  • 28
  • 29
  • have you tried this ?, what about bindView should I override that method too ? – Lukap Jan 20 '12 at 10:56
  • yes i have tried this and it works for me. i dont think u need to override the bindView method. – ASH Jan 23 '12 at 06:16
  • well my problem is if I do not override the bindView method the list is very slow and sluggish, so I will have to find the way to override correctly and tho have the animation played exactly ones. Because if I override in both methods the animation sometimes is played twice – Lukap Jan 23 '12 at 07:47
  • 4
    @ASH What is that flag variable in the line "if(flag == false)"? – Nitesh Kumar Oct 30 '15 at 05:52
  • @NiteshKhatri it is used to avoid animating cells that are currently being displayed at that moment – anonymous Apr 05 '16 at 16:36
7

The official docs about animation in Android say that you can set an animation to trigger whenever the layout is changed, using android:animateLayoutChanges="true".

Taken from: http://developer.android.com/training/animation/layout.html

René M
  • 698
  • 1
  • 5
  • 5
5

Adding this kind of animations is harder than I first thought of. There are two ways depending of the kind of animation you are trying to achieve.

This is quite a hack but the only way I found to add an animation to ListView's children is the following:

You can try notifying the adapter the id of the item you are willing to delete and call adapter.notifyDataSetChanged();. This will generate calls to the adapter's getView() method. Inside it you can do something like:

if ( item.getId() == itemToRemove ) {
 //apply the animation
}

After the animation finished you can recall adapter.notifyDataSetChanged() to put everything in place.

Macarse
  • 91,829
  • 44
  • 175
  • 230