15

在 Android 的ListView小部件中,将保存从内部类中的适配器方法ListView获得的视图。getViewRecycleBin

如何清除中的视图RecycleBin并强制ListView重新创建所有子视图。

4

5 回答 5

43

调用invalidate()invalidateViews()对我没有用(如正确答案中所述)。回收的视图仍然存储在ListView中。我不得不深入研究 Android 源代码以找到解决方案。我检查了许多方法,包括ListView类的setAdapter()方法( Android API 15):

@Override
public void setAdapter(ListAdapter adapter) {

    // ...
    mRecycler.clear();
    // ...

}

正如您所注意到的,设置适配器会清除回收器,它将所有回收的视图保存在列表视图中。您不必创建新适配器,设置相同的适配器足以清除列表视图中的回收视图列表:

Adapter adapter = listview.getAdapter ();
// ... Modify adapter ... do anything else you need to do
// To clear the recycled views list :
listview.setAdapter ( adapter );
于 2013-04-28T09:43:38.553 回答
4

If I remember correctly a call to invalidate on a ListView widget will empty the cache of Views which are currently stored. I would advise against emptying the cache of views of a ListView because of the potential performance issues.

If you're not going to use the convertView item then you'll end up with having to build the row view each time(resulting in a lot of objects constructed each time the user scrolls) + the extra memory occupied by the recycled views from the RecycleBin which will never be used anyway.

于 2012-08-21T07:14:45.337 回答
2

ListView-中有一个特殊的方法reclaimViews(List<View>)。它将当前正在使用和回收站中的所有项目移动到指定列表。Adapter小部件将在下次渲染之前为项目请求新视图。

如果项目结构没有太多更改,您可以使用回收的视图,或者完全废弃它们。例如,当用户更改选择颜色时,我正在使用此方法动态更新项目的背景可绘制对象。

于 2015-01-15T08:20:06.403 回答
0

从 ArrayList 或您在自定义适配器中使用的数据结构中删除回收站对象,并调用notifyDataSetChanged适配器的方法。

于 2012-08-21T06:22:20.513 回答
0

在我看来, @nekavally提供了最好的解决方案。我有一个ListView和一个SimpleCursorAdapter。有时我需要更改列表项的大小。但是由于适配器回收视图,它们可能会以错误的方式出现。所以我只是mListView.invalidateViews()在回收回收的视图后打电话,它工作得很好。

startAnimation(initialHeight, finalHeight, duration, new ValueAnimator.AnimatorUpdateListener() {
                    @Override
                    public void onAnimationUpdate(ValueAnimator animation) {
                        childView.getLayoutParams().height = 
                                (Integer) animation.getAnimatedValue();
                        childView.requestLayout();

                        if (animation.getAnimatedFraction() == 1f) {
                            mListView.reclaimViews(new ArrayList<View>());
                            mListView.invalidateViews();
                        }
                    }
                });
于 2018-02-08T14:59:25.947 回答