1

给定一个具有对象列表的数据模型,这些对象具有自己的列表作为属性:

private ObservableArrayList<BasProduct> basProducts = new ObservableArrayList<>();

//the model BasProduct have below attribute
public List<String> newOrderNotes;
public List<BasGoods> basGoodses;

我如何RecyclerView.Adapter根据这些数据制作一个?

4

1 回答 1

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()所以我为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- 将展平位置映射到组/子位置,甚至是组/子模型项本身。

所有这些迭代都是很多开销。我只是展示了如何以一种非常容易理解的方式来处理扁平化列表。

总而言之:您的数据是二维的。您设备上的列表是一维的。想想你的数据在设备上应该是什么样子,然后写一个适配器来做这件事。

于 2016-07-07T15:21:22.853 回答