给定一个数据模型,其中包含具有自己的列表作为属性的对象列表:
private ObservableArrayList<BasProduct> basProducts = new ObservableArrayList<>();
//the model BasProduct have below attribute
public List<String> newOrderNotes;
public List<BasGoods> basGoodses;
如何制作基于此数据的RecyclerView.Adapter
?
答案 0 :(得分:1)
您的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
- 将展平的位置映射到组/子位置,甚至是组/子模型项本身。
所有迭代都是很多开销。我只是展示了如何以一种非常易于理解的方式处理列表。
总而言之:您的数据是二维的。您设备上的列表是一维的。考虑一下您的数据在设备上应该是什么样子,并编写一个执行此操作的适配器。