views:

269

answers:

4

In iOS, there is a very easy and powerful facility to animate the addition and removal of UITableView rows, here's a clip from a youtube video showing the default animation. Note how the surrounding rows collapse onto the deleted row. This animation helps users keep track of what changed in a list and where in the list they were looking at when the data changed.

Since I've been developing on Android I've found no equivalent facility to animate individual rows in a TableView. Calling notifyDataSetChanged() on my Adapter causes the ListView to immediately update its content with new information. I'd like to show a simple animation of a new row pushing in or sliding out when the data changes, but I can't find any documented way to do this. It looks like LayoutAnimationController might hold a key to getting this to work, but when I set a LayoutAnimationController on my ListView (similar to ApiDemo's LayoutAnimation2) and remove elements from my adapter after the list has displayed, the elements disappear immediately instead of getting animated out.

I've also tried things like the following to animate an individual item when it is removed:

@Override
protected void onListItemClick(ListView l, View v, final int position, long id) {
    Animation animation = new ScaleAnimation(1, 1, 1, 0);
    animation.setDuration(100);
    getListView().getChildAt(position).startAnimation(animation);
    l.postDelayed(new Runnable() {
        public void run() {
            mStringList.remove(position);
            mAdapter.notifyDataSetChanged();
        }
    }, 100);
}

However, the rows surrounding the animated row don't move position until they jump to their new positions when notifyDataSetChanged() is called. It appears ListView doesn't update its layout once its elements have been placed.

While writing my own implementation/fork of ListView has crossed my mind, this seems like something that shouldn't be so difficult.

Thanks!

A: 

Since ListViews are highly optimized i think this is not possible to accieve. Have you tried to create your "ListView" by code (ie by inflating your rows from xml and appending them to a LinearLayout) and animate them?

Mannaz
It doesn't make sense to reimplement the listview just to add animations.
Macarse
I certainly could just use a `LinearLayout`, however with very large datasets `LinearLayout`'s performance will become abysmal. `ListView` has lots of smart optimizations around view recycling that allow it to handle large data sets (iOS's UITableView has the same optimizations). Writing my own view recycler falls under the category of reimplementing ListView :(
Alex Pretzlav
I know it doesnt make sense - but if you work with just some few rows the benefit of having nice in/out animations could be worth the try.
Mannaz
+2  A: 

Since Android is open source, you don't actually need to reimplement ListView's optimizations. You can grab ListView's code and try to find a way to hack in the animation, you can also open a feature request in android bug tracker (and if you decided to implement it, don't forget to contribute a patch).

FYI, the ListView source code is here: http://android.git.kernel.org/?p=platform/frameworks/base.git;a=blob;f=core/java/android/widget/ListView.java;h=892c44af7ffc4605004971b2d6dce88c065f1c76;hb=HEAD

Lie Ryan
+1  A: 

Have you considered animating a sweep to the right? You could do something like drawing a progressively larger white bar across the top of the list item, then removing it from the list. The other cells would still jerk into place, but it'd better than nothing.

Sam Dufel
A: 

In future (once Flex runs faster on Android) you could program this animation in Adobe Flex. I realize, that this is probably not the answer you're looking for, but I've seen similar animations done easily in Flex programs and also Adobe has recently released Air Runtime to Android market, so I've decided to mention the Flex alternative here. It runs Flash/ActionScript well, but Flex is slow at the moment.

Alexander Farber