2016-02-08 2 views
-2

У меня есть RecyclerView с реализацией RecyclerView.Adapter, которая имеет список объектов плюс заголовок и нижний колонтитул, и я включаю viewType, чтобы отображать заголовок для позиции 0 и нижний колонтитул для позиции getItemCount() (моя реализация «getItemCount()» возвращает «data.size() + 2» для размещения в верхнем и нижнем колонтитуле). Все это отлично работает, заголовок и нога отображаются в правильных местах, но когда я дойду до конца списка, а нижний колонтитул показан, я загружаю больше данных и добавляю их в свой список «данных», а затем я хочу, чтобы нижний колонтитул, который будет заменен следующим загруженным представлением данных, но этого не происходит. Я пробовал использовать различные методы notifyX на адаптере, но кажется, что он не обновляется до тех пор, пока я не прокручу список (и тогда все будет работать так, как я хочу).RecyclerView не обновляет свои представления при обновлении новыми данными

Что мне здесь не хватает? Как заставить RecyclerView перерисовать последний элемент в списке?

Мой адаптер:

private class TransactionsAdapter extends RecyclerView.Adapter { 
     private List transactions; 

     private static final int TYPE_HEADER = 0; 
     private static final int TYPE_ITEM = 1; 
     private static final int TYPE_FOOTER = 2; 

     private TransactionsAdapter(List transactions) { 
      this.transactions = transactions; 
     } 

     public void add(Transaction transaction) { 
      transactions.add(transaction); 
      notifyItemInserted(transactions.size()); 
     } 

     @Override 
     public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { 
      if(viewType == TYPE_HEADER) { 
       ViewHolder vh = new ViewHolder(inflate(getContext(), R.layout.postings_list_header, null), TYPE_HEADER); 
       return vh; 
      } else if(viewType == TYPE_FOOTER) { 
       ViewHolder vh = new ViewHolder(inflate(getContext(), R.layout.postings_list_footer, null), TYPE_FOOTER); 
       return vh; 
      } 
      SlidingCellView cellView = new SlidingCellView(getContext()); 
      cellViews.add(cellView); 
      ViewHolder vh = new ViewHolder(cellView, TYPE_ITEM); 
      return vh; 
     } 

     @Override 
     public void onBindViewHolder(ViewHolder holder, final int position) { 
      if (holder.getType() == TYPE_HEADER) { 
       final TextView text = (TextView) holder.itemView.findViewById(R.id.postings_header_text); 
       text.setText("Dette er nu godt"); 
      } else if (holder.getType() == TYPE_ITEM) { 
       final Transaction transaction = transactions.get(position - 1); 

       ((SlidingCellView) holder.itemView).update(new SlidingCellView.SlidingCellViewResources() { 
        @Override 
        public String getSlidingCellName() { 
         return transaction.getText(); 
        } 
       }); 
      } else if (holder.getType() == TYPE_FOOTER) { 
       final TextView text = (TextView) holder.itemView.findViewById(R.id.no_more_postings); 
       if(transactions.size() == 0) { 
        text.setText(getResources().getString(R.string.no_postings)); 
       } else { 
        if(resources.getTransactions().hasMore()) { 
         text.setText(getResources().getString(R.string.more_postings)); 
        } else { 
         text.setText(getResources().getString(R.string.end_of_postings)); 
        } 
       } 
      } 
     } 

     @Override 
     public int getItemCount() { 
      return transactions.size() + 2; 
     } 

     @Override 
     public int getItemViewType(int position) { 
      if(position == 0) { 
       return TYPE_HEADER; 
      } 
      if(position == transactions.size() + 1) { 
       return TYPE_FOOTER; 
      } 
      return TYPE_ITEM; 
     } 

     public class ViewHolder extends RecyclerView.ViewHolder { 
      private int type; 

      public ViewHolder(View itemView, final int type) { 
       super(itemView); 
       this.type = type; 
      } 

      public int getType() { 
       return type; 
      } 
     } 

    }

Код, добавить к операциям:

public void transactionsAdded() { 
     for (Transaction trans : resources.getTransactions()) { 
      postingsListAdapter.add(trans); 
     } 
    }

Так что, если я прокручиваю в нижней части списка, вид "R.layout.postings_list_footer" правильно отображается в нижней части списка, а затем, когда возвращается служебный вызов (код не показан), вызывается «transactionAdded», и я ожидаю, что список перерисовывает себя и, таким образом, отобразит последний показанный элемент как обычный элемент, а не нижний колонтитул, но это происходит только тогда, когда я начинаю прокручивать список. Спасибо
Сорен

+1

plz опубликовать свой код –

+0

Среднее, нижний колонтитул не отображается в последний раз? –

+1

Нижний колонтитул отображается как ожидалось, но когда я добавляю в список, я ожидаю, что последний показанный элемент в списке (который уже не является последним элементом в списке) будет нормальным элементом, а не нижним колонтитулом, но это происходит только тогда, когда я начните прокрутку. – Neigaard

ответ

0

Вы можете добавить к onBindViewHolder:

 if (position == getItemCount() - 1) { 
      // request more transactions 
     } 

Тогда ваш обратный вызов вызывает метод добавления, который должен вызвать notifyDataSetChanged:

public void add(Transaction transaction) { 
     transactions.add(transaction); 
     notifyDataSetChanged(); 
    } 

Существует рабочий пример без колонтитула here.

Если вам нужна хорошая библиотека, чтобы легко обрабатывать верхние и нижние колонтитулы в вашем RecyclerView, вы должны попробовать SectionedRecyclerViewAdapter.

+0

У меня нет проблем с выяснением того, что мне нужно запросить больше транзакций, и у меня это работает, но обновление RecyclerView не работает – Neigaard

Смежные вопросы