2016-07-07 2 views
0

Предоставлена ​​моделью данных со списком объектов, которые имеют свои собственные списки в качестве свойств:Как сделать адаптер RecyclerView для модели данных с вложенными списками

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

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

как мне сделать RecyclerView.Adapter, который основан на эти данные?

ответ

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 –, который отображает сплющенные позиции в позиции группы/ребенка или даже элементы самой группы/дочерней модели.

Вся эта итерация - это много накладных расходов. Я просто показываю, как обрабатывать выравнивание списка таким образом, который очень прост для понимания.

Итак, в сумме: Ваши данные двумерные. Список на вашем устройстве является одномерным. Подумайте, как будут выглядеть ваши данные на устройстве и напишите адаптер, который это сделает.

+0

Список имеет Список , и ему нужно использовать RecyclerView для добавления xml в rander – user6315082

+0

Мне очень понравился ваш ответ, но я сталкиваюсь с проблемами при его фактическом осуществлении. можете ли вы предоставить ссылку на какой-нибудь примерный код? –