【问题标题】:RecyclerView with GridLayoutManager inside RecyclerView with LinearLayoutManagerRecyclerView 与 GridLayoutManager 在 RecyclerView 中与 LinearLayoutManager
【发布时间】:2017-01-16 13:54:54
【问题描述】:

我基本上是在尝试实现这个设计原则(from Google's Material Design): 因此,我用LinearLayoutManager 创建了一个父RecyclerView,然后在RecyclerView 适配器中,我将子RecyclerViewGridLayoutManager 放在“富媒体”部分(行动区2) .一切正常,除了我将内部RecyclerView 网格设置为具有match_parent 宽度和wrap_content 高度,但它不会正确计算内容的大小,似乎将其保留在0 & 因此隐藏。如果我将孩子RecyclerView 设置为特定高度,则项目会显示在其中,但当然会在底部被切断。 其他人似乎遇到过这个问题,but in their case, both have linear layouts。 (另见"Khay's" answer here。)

现在我的问题是,如何覆盖onMeasure 方法,就像“pptang”在上面链接问题的已接受答案中所做的那样,但在自定义GridLayoutManager 而不是自定义LinearLayoutManager 中?我没有在这里发布我的代码,因为它与链接的代码基本相同,只是我需要为孩子RecyclerView 制作一个自定义GridLayoutManager,以便它正确测量为“pptang”的答案状态。

否则,有没有比在第二个 RecyclerView 中使用 1 个 RecyclerView 更好的方法?只有 1 个 RecyclerView 可以同时使用上述CardViews 的列表和每个CardView 中的唯一项目网格来填充活动/片段吗?

【问题讨论】:

  • 根据材料设计指南“将补充动作限制为两个动作”。您要在父列表中添加多少项?滚动将如何工作?网格和列表都使用垂直滚动?
  • 我想要几个ViewPager标签;一个有 3 个父 CardViews,另一个可能有 8 个父 CardViews,另一个有大约 5 个父 CardViews。目的是让网格完全“打开”,因此没有内部滚动,只有父 CardViews 才能垂直滚动。根据我所见,将一个RecyclerView 放在另一个内部也会干扰工具栏隐藏(CoodinatorLayout),如果您尝试通过按住RecyclerView 网格进行滚动,工具栏不会隐藏,而只会隐藏抱着孩子外面的某个地方时隐藏RecyclerViews
  • 我想我可能已经偏离了你实际询问@masp 的内容。对不起。在个人CardViews 中,我只想在顶部放置标题和图标,在中心放置网格,并使用“扩展器”来隐藏一些支持文本。可能还赋予Cardview's 标题部分隐藏/折叠和显示/展开网格的能力,例如ExpandableListView
  • 您说“目的是让网格完全“打开”,因此,没有内部滚动,只有父 CardViews 垂直滚动。”这意味着您不需要回收站视图中的回收站视图。一个 Gridlayout 管理器就足够了。我还没有尝试过@Gustavo 的建议,所以我不知道它是否会涵盖您所要求的所有内容,但它的方向是正确的。
  • 我没有遵循你的思路,@masp。我使用了与@Gustavo 建议的方法类似的方法(请参阅我的评论中的链接),但它给出的结果与谷歌插图完全不同。我不想在另一个里面使用RecyclerView,但是我看不到任何其他方法可以达到上述效果。我没有提到ListView/GridView/etc,因为RecyclerView 替换了它们,那么还有其他方法吗?你如何让 1 个RecyclerView 列出CardViews 并在每个CardViews 中动态填充一个网格?

标签: android android-recyclerview material-design android-cardview gridlayoutmanager


【解决方案1】:

您可以使用库 SectionedRecyclerViewAdapter 仅使用一个 RecyclerView 构建它。

您可以在here下方找到图片示例的完整代码。

首先创建一个Section类:

class MySection extends StatelessSection {

    String title;
    String subtitle;
    List<String> list;

    public MySection(String title, String subtitle, List<String> list) {
        // call constructor with layout resources for this Section header, footer and items 
        super(R.layout.section_header, R.layout.section_item);

        this.title = title;
        this.subtitle = subtitle;
        this.list = list;
    }

    @Override
    public int getContentItemsTotal() {
        return list.size(); // number of items of this section
    }

    @Override
    public RecyclerView.ViewHolder getItemViewHolder(View view) {
        // return a custom instance of ViewHolder for the items of this section
        return new MyItemViewHolder(view);
    }

    @Override
    public void onBindItemViewHolder(RecyclerView.ViewHolder holder, int position) {
        MyItemViewHolder itemHolder = (MyItemViewHolder) holder;

        // bind your view here
        itemHolder.tvItem.setText(list.get(position));
    }

    @Override
    public RecyclerView.ViewHolder getHeaderViewHolder(View view) {
        return new SimpleHeaderViewHolder(view);
    }

    @Override
    public void onBindHeaderViewHolder(RecyclerView.ViewHolder holder) {
        MyHeaderViewHolder headerHolder = (MyHeaderViewHolder) holder;

        // bind your header view here
        headerHolder.tvTitle.setText(title);
        headerHolder.tvSubTitle.setText(subtitle);
    }
}

然后你用你的部分设置 RecyclerView:

// Create an instance of SectionedRecyclerViewAdapter 
SectionedRecyclerViewAdapter sectionAdapter = new SectionedRecyclerViewAdapter();

// Create your sections with the list of data for each year
MySection section1 = new MySection("Title", "Subhead", firstDataList);

// Add your Sections to the adapter
sectionAdapter.addSection(section1);

// Set up your RecyclerView with the SectionedRecyclerViewAdapter
GridLayoutManager glm = new GridLayoutManager(getContext(), 2);
glm.setSpanSizeLookup(new GridLayoutManager.SpanSizeLookup() {
    @Override
    public int getSpanSize(int position) {
        switch(sectionAdapter.getSectionItemViewType(position)) {
            case SectionedRecyclerViewAdapter.VIEW_TYPE_HEADER:
                return 2;
            default:
                return 1;
        }
    }
});
recyclerView.setLayoutManager(glm);
recyclerView.setAdapter(sectionAdapter);

【讨论】:

  • here 学到的,我明白你在说什么,这实际上是我以前所拥有的。不过,这不是我想要的,我实际上希望CardView 成为该部分,其中的元素就像谷歌自己所说明的那样,并且让那些CardViews 自己在RecyclerView 中。如何做到这一点才能达到与 Google 所展示的结果相同的结果?
  • 有更简单的库来支持带有自定义布局管理器RendererRecyclerViewAdapter 的嵌套回收器视图,请参阅 CompositeViewRenderer。也请在这个答案中掠夺stackoverflow.com/a/48464993/4894238
【解决方案2】:

总结一下。 您不应该在回收站内使用回收站。您需要实现一个自定义的 gridLayoutManager。要实现这一点,请阅读以下内容:

来自文档https://developer.android.com/reference/android/support/v7/widget/RecyclerView.ItemDecoration.html

ItemDecoration 允许应用程序向适配器数据集中的特定项目视图添加特殊的绘图和布局偏移。这对于在项目、突出显示、视觉分组边界等之间绘制分隔线很有用。

因此,如果您将上述内容与http://blog.sqisland.com/2014/12/recyclerview-grid-with-header.html 一起使用,您绝对可以实现您想要的。只需将您从材料指南中呈现的图像视为 gridLayoutManager 中的一个组。

  • 您可以拥有不同类型的视图
  • 每一行可能有多个视图
  • 每一行的装饰可能不同

【讨论】:

  • 我明白你的意思,并同意RecyclerView 中的RecyclerView 是错误的。但是,用边界对它们进行分组只会达到与上述相似的结果,而不是相同的结果,因为那是实际的CardView,而不仅仅是分组。那么问题就变成了,我们如何从简单的分组到实际的CardViews
猜你喜欢
  • 1970-01-01
  • 2015-08-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-02-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多