简体   繁体   English

RecyclerView可以为每个项目实例化多个“视图”吗?

[英]Can a RecyclerView instantiate more than one 'view' per item?

TLDR: TLDR:

Usually, in a RecyclerView implementation, between the Adapter and the LayoutManager , there is a one-view-per-item ratio. 通常,在RecyclerView实现中,在AdapterLayoutManager ,每个项目一个视图的比率。 We are hoping to find a way to create multiple views per item. 我们希望找到一种为每个项目创建多个视图的方法。

Note: Please don't confuse this with being able to create different view types based on adapter position. 注意:请不要将此与能够根据适配器位置创建不同的视图类型混淆。 For simplicity assume there is only one view type. 为了简单起见,假设只有一种视图类型。

Full Question: 完整问题:

For our project, we need to create a multi-column list. 对于我们的项目,我们需要创建一个多列列表。 A multi-column list is visually identical to a grid, but has one noticeable difference; 多列列表在外观上与网格相同,但有一个明显的区别。 in a grid (like that created with GridLayoutAdapter ), one 'cell' (ie View / ViewHolder ) represents one item. 在网格中(如使用GridLayoutAdapter创建的网格),一个“单元格”(即View / ViewHolder )代表一项。 In a multi-column list, one row represents one item. 在多列列表中, 一行代表一项。 The cells that make up that row each display different properties of that same, single item. 组成该行的单元格每个都显示相同的单个项目的不同属性。

As an example, say I have a list of ten Foo objects, and Foo defines five properties which we want to display in columns. 例如,假设我有一个包含十个Foo对象的列表,并且Foo定义了五个要在列中显示的属性。 From the perspective of our dataset, there are ten items. 从我们的数据集的角度来看,有十个项目。 From the perspective of the LayoutManager however, there are fifty (ten items (the rows) times five cells (the columns) per row/item.) 但是,从LayoutManager的角度来看,每行/每个项目有五十个(十个项目(行)乘以五个单元格(列)。)

The approach I'm leaning to is to create a co-dependent RecyclerView.Adapter / RecyclerView.LayoutManager pair. 我倾向于采用的方法是创建一个相互依赖的RecyclerView.Adapter / RecyclerView.LayoutManager对。

First, in my adapter subclass, in addition to creating a property to hold my data items, I also added a 'columnCount' property. 首先,在我的适配器子类中,除了创建一个保存数据项的属性外,我还添加了一个“ columnCount”属性。 Then in the getItemCount() override, rather than returning the number of items like one would normally do, I instead return the number of items multiplied by the columnCount, like so: 然后在getItemCount()覆盖中,而不是像通常那样返回项目数,而是返回将项目数乘以columnCount,如下所示:

private List<Object> items;
public List<Object> getItems(){
    return items;
}
public void setItems(List<Object> items){
    this.items = items;
    notifyDataSetChanged();
}

private int columnCount = 1;
public int getColumnCount(){
    return columnCount;
}
public void setColumnCount(int columnCount){
    this.columnCount = Math.max(columnCount, 1);
    notifyDataSetChanged();
}

@Override public final int getItemCount(){
     return getItems().size() * getColumnCount();
}

Next in my RecyclerView.LayoutManager subclass, I configure it to grab the passed-in adapter, and if I can cast it to my specific adapter type, then I can get the number of columns and use that for my layout calculations. 接下来,在RecyclerView.LayoutManager子类中,将其配置为获取传入的适配器,如果可以将其强制转换为特定的适配器类型,则可以获取列数并将其用于布局计算。 If it's not the right type of adapter, I just treat it as if there's only one column. 如果不是正确的适配器类型,我将其视为只有一列。

Now while this approach seems to work, it muddies up the API a little as getItemCount() no longer returns the count of actual items, but rather the count of views, which may be confusing to a user. 现在,尽管这种方法似乎可行,但由于getItemCount()不再返回实际项目的数量,而是视图的数量,这使API有点混乱,这可能会使用户感到困惑。 (I wish they had named it getViewCount() instead.) It also means again, that LayoutManager only works with a specific Adapter type. (我希望他们getViewCount()getViewCount() 。)这也意味着LayoutManager仅适用于特定的Adapter类型。

I had also considered making it look like multiple columns by using a horizontal LinearLayout to represent an entire row, then using that in a regular list, but that limited our flexibility (ie can't do fixed rows/columns, etc.) so we abandoned it. 我还考虑过使用水平的LinearLayout代表整个行,然后在常规列表中使用它,使其看起来像多列,但这限制了我们的灵活性(即,无法执行固定的行/列等),因此我们放弃了

I'm wondering if I'm approaching this wrong and/or if there's an API I can already use for this. 我想知道我是否正在解决这个错误和/或是否已经有一个我可以使用的API。 Is there such a thing, or am I on the correct approach? 有这样的事情吗,还是我采用正确的方法?

You can achieve this at the adapter level. 您可以在适配器级别实现此目的。 You will have to use these three methods. 您将必须使用这三种方法。

getItemViewType() 
onCreateViewHolder() 
onBindViewHolder()

Here is a working example for your help.Let me know if anything is not making sense. 这是一个为您提供帮助的有效示例。请让我知道是否有任何问题。 Just make your item a viewpager and add multiple pages of items. 只需将您的商品设为viewpager,然后添加多页商品即可。

https://guides.codepath.com/android/Heterogenous-Layouts-inside-RecyclerView https://guides.codepath.com/android/Heterogenous-Layouts-inside-RecyclerView

您可以拥有多个具有不同视图的视图持有者,因此根据类型可以使用不同的视图。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM