【问题标题】:Changing layout managers for different views in RecyclerView在 RecyclerView 中更改不同视图的布局管理器
【发布时间】:2016-05-29 04:22:30
【问题描述】:

我用列表中的子元素实现了一个可扩展的回收视图。我关注了这个code。这就是它的工作原理,

使用RecyclerView实现ExpandableListView简单介绍如下。列表模型有一个附加参数“type”,用于标识项目是标题还是子项。通过检查这个参数,适配器会膨胀对应类型的视图和视图持有者。如果类型为HEADER,则会膨胀header项的布局,其中包含一个TextView和一个ImageView,用于指示子树是否展开。

现在,我想做的是将展开的布局变成一个网格。我通常会通过将布局管理器设置为 GridLayoutManager 来做到这一点,但在这种情况下,我只使用一个 recyclerview,这意味着我不能在不更改标题的情况下更改布局管理器,这最终会导致整个 recyclerview 变成一个包括标题的网格。

我的问题是:您将如何为适配器内的几个布局更改布局管理器?

编辑:我添加了一些代码。

Recyclerview 适配器:

public class ExpandableListAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {

// These are constants that are used to determine if the item is a child or a header and is defined with each item from the data model
public static final int HEADER = 0;
public static final int CHILD = 1;

private List<Item> data;

public ExpandableListAdapter(List<Item> data) {
    this.data = data;
}

@Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int type) {
    View view = null;

    LayoutInflater inflater = (LayoutInflater) parent.getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);

    // Check whether the item is a header or child and inflate differnet layouts
    switch (type) {
        case HEADER:
            // Inflate a header layout if the item is a header
            view = inflater.inflate(R.layout.list_header, parent, false);
            ListHeaderViewHolder header = new ListHeaderViewHolder(view);
            return header;
        case CHILD:
            // Inflate a child layout if the item is a child
            view = inflater.inflate(R.layout.list_child, parent, false);
            ListChildViewHolder child = new ListChildViewHolder(view);
            return child;
    }
    return null;
}

public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
    final Item item = data.get(position);

    // Bind different layouts based on if the item is a header or child
    switch (item.getType()) {
        case HEADER:
            // ...
        case CHILD:
            // ...
    }
}

@Override
public int getItemViewType(int position) {
    return data.get(position).type;
}

@Override
public int getItemCount() {
    return data.size();
}

// Viewholder for the header items
private static class ListHeaderViewHolder extends RecyclerView.ViewHolder {
    // ...
}

// Viewholder for the child items
private static class ListChildViewHolder extends RecyclerView.ViewHolder {
    // ...
}

这是我声明布局管理器的主要活动:

recyclerview = (RecyclerView) findViewById(R.id.recyclerview);
recyclerview.setLayoutManager(new LinearLayoutManager(this, LinearLayoutManager.VERTICAL, false));

【问题讨论】:

    标签: android android-layout android-recyclerview


    【解决方案1】:

    您可以将布局管理器更改为 GridLayoutManager 并为标题定义“跨度大小”,例如,如果您想要具有 2 列的网格,则标题的跨度大小应为 2,子项的跨度大小为 1:

        GridLayoutManager glm = new GridLayoutManager(getContext(), 2);
        glm.setSpanSizeLookup(new GridLayoutManager.SpanSizeLookup() {
            @Override
            public int getSpanSize(int position) {
                switch(getTypeForPosition(position)) {
                    case HEADER:
                        return 2;
                    default:
                        return 1;
                }
            }
        });
        recyclerView.setLayoutManager(glm);
    

    有一个使用library的标题here的可扩展网格的完整示例。

    【讨论】:

      【解决方案2】:

      将布局管理器更改为gridlayout管理器并按如下所述处理跨度大小

      layoutManager.setSpanSizeLookup(new GridLayoutManager.SpanSizeLookup() {
                  @Override
                  public int getSpanSize(int position) {
                      int type=mAdapter.getItemViewType(position);
                      if (type == "view holder type name")
                          return 2;
                      else
                          return 1;
                  }
              });
      

      【讨论】:

        最近更新 更多