【问题标题】:RecyclerView in a RecyclerView itemRecyclerView 项中的 RecyclerView
【发布时间】:2017-07-31 17:20:23
【问题描述】:

我知道这是一个坏主意,但我在另一个 RecyclerView 的项目中使用 RecyclerView 来显示包含列表的项目列表。

我设法让它工作并尽可能地对其进行了调整,但是当具有更多项目的列表开始显示并在屏幕上绘制时,我仍然会得到那些 green 尖峰。

这些尖峰在翻阅物品时会产生明显的延迟,并且在使用比三星 Galaxy S6 更慢和更旧的东西时更加明显。

我做了一些日志记录,似乎outer ViewHolders 正在被回收,而inner RecyclerView 的适配器只创建了 5 次,所以一定是绘制时间扼杀了性能。

通过设置 RecycledViewPool 中的 ViewHolder 的最大数量,我设法限制了新 inner RecyclerView 的 ViewHolders 的创建,但这仅起到了一点作用。

我知道内部 RecyclerView 没有“底部”,它可以依靠它来计算何时显示新项目,因此它必须立即绘制每个项目,这可能是不应该使用的主要原因这个设置。 (当我写下这个问题时,我才恍然大悟。谢谢世界上的橡皮鸭)。

有没有一种方法可以进一步调整,或者您能否建议如何在另一个 RecyclerView 的项目中使用除 RecyclerView 之外的其他设置来完成这项工作?

如果需要,我会提供更多信息。

谢谢

【问题讨论】:

  • 你想达到什么目的?
  • 在向提问者提出任何建议之前,请不要在此处对问题投反对票。
  • 试图了解下一步该做什么,以使此设置顺利​​进行,在进行时不会出现滞后或丢帧
  • 我的意思是,你为什么要尝试嵌套垂直滚动列表?
  • 嵌套的 reyclerview 也在 google io 2016 app twitter.com/crafty/status/799344328304783360

标签: android optimization android-recyclerview nestedrecyclerview


【解决方案1】:

最好的解决方案是切换回ListView 并使用ExpandableListView interface,或者在RecyclerView 上自行实现。

正如您所提到的 - 列出滚动组件从来都不是一个好的解决方案。这是一个示例可扩展列表视图适配器,因此您知道需要什么:

public class MyExpandableListAdapter extends BaseExpandableListAdapter {

    ...

    @Override
    public Object getChild(int listPosition, int childListPosition) { 
        //return an item that would have been in one of the nested recyclers
        //(listPosition = parent, childListPosition = nested item number)
       return getGroup(listPosition).getChildren().get(childListPosition);
    }

    @Override
    public int getChildrenCount(int listPosition) {
        //presuming the parent items contain the children
        return getGroup(listPosition).getChildren().size();
    }

    @Override
    public Object getGroup(int listPosition) {
        //group is the parent items (the tope level recycler view items)
        return mData.get(listPosition);
    }

    @Override
    public int getGroupCount() {
        return mData.size();
    }

    @Override
    public View getGroupView(int listPosition, boolean isExpanded, View convertView, ViewGroup parent) {
        if (convertView == null) {
            convertView = mInflater.inflate(R.layout.list_item, parent, false);
        }
        MyDataType item = getGroup(listPosition);
        //set the fields (or better yet, use viewholder pattern)
        return convertView;
    }

    @Override
    public View getChildView(int listPosition, final int expandedListPosition, boolean isLastChild, View convertView, ViewGroup parent) {
        if (convertView == null) {
            convertView = mInflater.inflate(R.layout.list_item, parent, false);
        }
        MyDataType item = getChild(listPosition, expandedListPosition);
        //set the fields (or better yet, use viewholder pattern)
        return convertView;
    }

}

【讨论】:

  • 谢谢,我会检查并尝试实现它。我相信 ListView 的时代已经结束,RecyclerView 是必须的,也是列表视图的霸主,但现在我发现如果你不尝试过多地弄乱它,它的效果最好
  • RecyclerView 修复了 ListView 的一些问题,但对于子项的情况,ExpandableListView 仍然可以完成很多您必须在 RecyclerView 中自己完成的工作。如果您确保使用 ViewHolder 模式并且只使用垂直列表,那么使用列表视图没有问题
【解决方案2】:

我通过创建共享 RecycledViewPool 设法获得了更好的性能,就像在 cmets 中链接的项目 @Raghunandan 中所做的那样。

Google I/O Android App - Shared RecycledViewsPool

我还设置了池的最大视图数量,这确实起到了作用,现在我只需要找到一种方法来重用我的监听器并避免创建新的监听器,但这是一个不同的问题。

感谢大家的回复。 如果我以后发现任何有用的东西,我会发布更多。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-01-09
    • 2016-02-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-08-31
    相关资源
    最近更新 更多