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!
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 aLinearLayout
) and animate them?call listView.scheduleLayoutAnimation(); before changing the list
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.
I hacked together another way to do it without having to manipulate list view. Unfortunately, regular Android Animations seem to manipulate the contents of the row, but are ineffectual at actually shrinking the view. So, first consider this handler:
Add this collection to your List adapter:
and add
Next, wherever it is that you want to hide a row, add this:
That's it! You can change the speed of the animation by altering the number of pixels that it shrinks the height at once. Not real sophisticated, but it works!
I have done something similar to this. One approach is to interpolate over the animation time the height of the view over time inside the rows
onMeasure
while issuingrequestLayout()
for the listView. Yes it may be be better to do inside the listView code directly but it was a quick solution (that looked good!)Take a look at the Google solution. Here is a deletion method only.
ListViewRemovalAnimation project code and Video demonstration
It needs Android 4.1+ (API 16). But we have 2014 outside.