在iOS中,有一个非常简单和强大的工具来动画添加和删除UITableView行,这是一个来自youtube视频的剪辑,显示默认动画。注意周围的行如何折叠到已删除的行上。这个动画帮助用户跟踪列表中发生了什么变化,以及当数据发生变化时他们正在查看列表中的哪个位置。

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.

我还尝试了如下方法,在移除单个项目时将其动画化:

@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);
}

但是,动画行周围的行不会移动位置,直到调用notifyDataSetChanged()时它们跳转到新位置。一旦元素被放置,ListView似乎不会更新它的布局。

虽然写我自己的ListView的实现/分支已经越过我的脑海,这似乎不应该是那么困难的事情。

谢谢!


当前回答

只是分享另一种方法:

首先设置列表视图的android:animateLayoutChanges为true:

<ListView
        android:id="@+id/items_list"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:animateLayoutChanges="true"/>

然后我使用一个处理程序来添加项目,并延迟更新listview:

Handler mHandler = new Handler();
    //delay in milliseconds
    private int mInitialDelay = 1000;
    private final int DELAY_OFFSET = 1000;


public void addItem(final Integer item) {
    mHandler.postDelayed(new Runnable() {
        @Override
        public void run() {
            new Thread(new Runnable() {
                @Override
                public void run() {
                    mDataSet.add(item);
                    runOnUiThread(new Runnable() {
                        @Override
                        public void run() {
                            mAdapter.notifyDataSetChanged();
                        }
                    });
                }
            }).start();

        }
    }, mInitialDelay);
    mInitialDelay += DELAY_OFFSET;
}

其他回答

由于Android是开源的,你实际上不需要重新实现ListView的优化。你可以抓取ListView的代码,并试图找到一种方法来破解动画,你也可以在android漏洞跟踪器中打开一个功能请求(如果你决定实现它,不要忘记贡献一个补丁)。

仅供参考,ListView的源代码在这里。

调用 listView.scheduleLayoutAnimation (); 在更改列表之前

插入新行到ListView后,我只是滚动ListView到新位置。

ListView.smoothScrollToPosition(position);

下面是允许您删除行和重新排序的源代码。

还提供了一个演示APK文件。删除行更多地沿着谷歌的Gmail应用程序的路线,在滑动顶视图后显示底部视图。底部视图可以有一个撤销按钮或任何你想要的。

因为ListViews是高度优化的,我认为这是不可能实现的。你有没有尝试过创建你的“ListView”的代码(即通过膨胀你的行从xml和追加到一个线性布局)和动画他们?