首页 > 解决方案 > 我是否破坏了回收者视图的性能和使用?

问题描述

因此,当我们想要显示大量元素时,我们应该使用回收器视图。
这样做的好处是视图被重复使用,因此我们不会膨胀列表中的每个视图并将它们保存在内存中,而只是将屏幕中显示的视图保存在内存中,以回收其余部分。
但是如果回收的视图本身就是一个“迷你”列表呢?
即对于每个回收的项目,我们通过删除所有子视图并添加新的子视图来更改其结构?
这是否违背了使用回收列表的整个想法?
有问题的示例(是传递给回收站视图持有者 itemInRecycler的垂直):LinearLayout

itemInRecycler.removeAllViews();  
for(element: elements) {  
   CustomView view = inflate();  
   view.setDisplayData(element);  
   itemInRecycler.addView(view);  
} 

标签: androidandroid-layoutandroid-activityandroid-recyclerviewandroid-linearlayout

解决方案


这是否违背了使用回收列表的整个想法?

itemView这取决于子列表占整个子列表的多少。如果子列表是您要显示的唯一内容,那么是的,您正在挫败很大一部分性能提升。每次绑定 时,您仍然在膨胀视图ViewHolder,这是您在使用 RecyclerView 时要避免的事情之一。

它还取决于子列表的大小。如果最多只有三个元素,那么成本就会降低。如果子列表是数百个项目,则成本很大。

一种选择是使用 sub-RecyclerView 而不是 LinearLayout,并将每个 sub-RecyclerView 连接到同一个sharedRecycledViewPool。通过这种方式,您可以获得 RecyclerView 与可滚动的 LinearLayout 的所有好处,但更好的是,因为每个子 RecyclerView 都可以从其他子 RecyclerView 获取 ViewHolders。

如果这对您来说有点过于苛刻,您可能会优化您已经编写的代码。您可以重复使用现有视图(如果不够,只创建新视图),而不是每次清除列表然后重新增加正确数量的视图,如果有太多视图,则删除额外的视图。

int i = 0;

// reuse existing views
for (; i < elements.size() && i < itemInRecycler.getChildCount(); i++) {
    Element element = elements.get(i);
    CustomView view = (CustomView) itemInRecycler.getChildAt(i);
    view.setDisplayData(element);
}

// create new views if there weren't enough to reuse
for (; i < elements.size(); i++) {
    Element element = elements.get(i);
    CustomView view = inflate();
    view.setDisplayData(element);
    itemInRecycler.addView(view);
}

// remove any extras after we've reused everything
int viewsToRemove = itemInRecycler.getChildCount() - i;

if (viewsToRemove > 0) {
    itemInRecycler.removeViews(i, viewsToRemove);
}

例如,在elements集合始终包含 5 到 7 个元素的世界中,这种方法将确保您始终重复使用前 5 个元素,CustomView然后只增加或删除 0-2 个额外CustomView的元素。


推荐阅读