您的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()
所以我为and编写了实现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()
and 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
- 将展平位置映射到组/子位置,甚至是组/子模型项本身。
所有这些迭代都是很多开销。我只是展示了如何以一种非常容易理解的方式来处理扁平化列表。
总而言之:您的数据是二维的。您设备上的列表是一维的。想想你的数据在设备上应该是什么样子,然后写一个适配器来做这件事。