Ваш 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
–, который отображает сплющенные позиции в позиции группы/ребенка или даже элементы самой группы/дочерней модели.
Вся эта итерация - это много накладных расходов. Я просто показываю, как обрабатывать выравнивание списка таким образом, который очень прост для понимания.
Итак, в сумме: Ваши данные двумерные. Список на вашем устройстве является одномерным. Подумайте, как будут выглядеть ваши данные на устройстве и напишите адаптер, который это сделает.
Список имеет Список , и ему нужно использовать RecyclerView для добавления xml в rander –
user6315082
Мне очень понравился ваш ответ, но я сталкиваюсь с проблемами при его фактическом осуществлении. можете ли вы предоставить ссылку на какой-нибудь примерный код? –