您的RecyclerView 列表视图是一维的。您的列表模型是二维的。因此,您需要一个列表适配器,将您的二维模型展平为一维模型。
假设你有这个模型:
BasProduct[0]
OrderNote[0]
OrderNote[1]
BasGoods[0]
BasGoods[1]
BasProduct[1]
OrderNote[0]
OrderNote[1]
BasGoods[0]
BasGoods[1]
即您有两个产品,每个产品的两个列表中都有两个项目。
现在你只需要把它变成这样:
[0] BasProduct[0]
[1] OrderNote[0]
[2] OrderNote[1]
[3] BasGoods[0]
[4] BasGoods[1]
[5] BasProduct[1]
[6] OrderNote[0]
[7] OrderNote[1]
[8] BasGoods[0]
[9] BasGoods[1]
有很多方法可以做到这一点,诀窍是设计一种方法,这样您就不会编写隐藏大量错误的混淆代码。
我所做的是使用ExpandableListAdapter 作为模板并从那里构建。所以我为getGroupCount() 和getChildCount() 编写了实现。然后我使用这些方法实现了getItemCount():
@Override
public int getItemCount() {
int count = 0;
int groupCount = getGroupCount();
for (int i = 0; i < groupCount; i++) {
count++;
if (mGroupExpanded[i]) {
count += getChildCount(i);
}
}
return count;
}
您可以在我的代码中看到我有一个组扩展标志的布尔数组。我让我的RecyclerView 拥有可展开的组,因此这意味着需要更多代码来跟踪展开/折叠状态。
按照相同的模式,我将绑定拆分为onBindGroupViewHolder() 和onBindChildViewHolder(),然后使用这些方法实现onBindViewHolder():
@Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
int pos = 0;
int groupCount = getGroupCount();
for (int i = 0; i < groupCount; i++) {
if (pos == position) {
onBindGroupViewHolder(holder, i);
return;
}
pos++;
if (mGroupExpanded[i]) {
int childCount = getChildCount(i);
for (int j = 0; j < childCount; j++) {
if (pos == position) {
onBindChildViewHolder(holder, i, j);
return;
}
pos++;
}
}
}
throw new IllegalStateException("couldn't determine group/child for raw position = " + position);
}
那么你需要的最后一块是将getAdapterPosition()返回的扁平位置映射回组位置和子位置:
private int[] getGroupChildPosition(int position) {
// positions[0] is group position
// positions[1] is child position, -1 means it's a group
int[] positions = new int[2];
int current = 0;
int groupCount = getGroupCount();
for (int currentGroup = 0; currentGroup < groupCount; currentGroup++) {
if (current == position) {
positions[0] = currentGroup;
positions[1] = -1;
return positions;
}
current++;
if (mGroupExpanded[i]) {
int childCount = getChildCount(i);
for (int currentChild = 0; currentChild < childCount; currentChild++) {
if (current == position) {
positions[0] = currentGroup;
positions[1] = currentChild;
return positions;
}
current++;
}
}
}
throw new IllegalStateException("couldn't determine group/child for raw position = " + position);
}
你可以做不同的事情。例如,您可以创建一个Map——实际上是一个SparseArray——将展平位置映射到组/子位置,甚至是组/子模型项本身。
所有的迭代都是很多开销。我只是展示了如何以一种非常容易理解的方式来处理扁平化列表。
总而言之:您的数据是二维的。您设备上的列表是一维的。想想你的数据在设备上应该是什么样子,然后编写一个适配器来实现这一点。