ViewHolder возвращает старую позицию в RecyclerView - PullRequest
0 голосов
/ 14 февраля 2020

У меня есть Фрагмент с BottomSheet , который содержит горизонтальное RecyclerView . RecyclerView настраивается с помощью SnapHelper для достижения эффекта страницы. Это выглядит примерно так:

enter image description here

В событии onCreateView в Фрагмент , я установил Адаптер и LayoutManager :

recycler_view.setAdapter(new MyRecyclerAdapter(getContext(), dataList));
recycler_view.setLayoutManager(new LinearLayoutManager(getContext(), LinearLayoutManager.HORIZONTAL, false));

После того, как я установил Адаптер , событие onCreateViewHolder запускается в MyRecyclerAdapter объект класса, за которым следует onBindViewHolder :

@Override
public MyRecyclerAdapter.MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
    View view = inflater.inflate(R.layout.fragment_recycler_item, parent, false);
    return new MyViewHolder(view, parent);
}

@Override
public void onBindViewHolder(MyRecyclerAdapter.MyViewHolder viewHolder, int position) {
    /**I do something using position**/
}

Когда я создаю этот Фрагмент и настраиваю RecyclerView для первого время-все работает хорошо, onBindViewHolder возвращает правильную позицию. Но когда я переключаюсь на 1, 2 и т. Д. c. элемент RecyclerView , а затем воссоздать фрагмент по неизвестной причине onBindViewHolder вернуть старую (последнюю) позицию, хотя новые Adapter и LineraLayoutManager были созданы.

Для ясности я разбью его на этапы:

  1. Создание Фрагмента .
  2. Создание объекта класса MyRecyclerAdapter . Установите его в RecyclerView .
  3. Создание объекта класса LinearLayoutManager . Установите его в RecyclerView .
  4. Событие onBindViewHolder в MyRecyclerAdapter запущено. Я получаю position = 0 .
  5. Я выделяю элемент с position = 2 .
  6. Я отсоединяю этот фрагмент, а затем сразу присоединяю этот фрагмент.
  7. Создание объекта класса MyRecyclerAdapter . Установите его в RecyclerView .
  8. Создание объекта класса LinearLayoutManager . Установите его в RecyclerView .
  9. Событие onBindViewHolder в MyRecyclerAdapter запущено. Я получаю position = 2 .

Вопрос: Почему я получаю старую позицию и, самое главное, как ее исправить?

Я читал, что Android специально сохраняет старый ViewHolder для более эффективного использования памяти, но мне это не нужно.

UPD (решение) : Мне кажется, что это временное решение (не идеальное), но оно работает. Вам необходимо запустить smoothScrollToPosition (0) после того, как вы установили Adapter и LayoutManager . Очень важно использовать smoothScrollToPosition (0) , а не scrollToPosition (0) :

recycler_view.setAdapter(new MyRecyclerAdapter(getContext(), dataList));
recycler_view.setLayoutManager(new LinearLayoutManager(getContext(), LinearLayoutManager.HORIZONTAL, false));
recycler_view.smoothScrollToPosition(0);

UPD.1 (лучшее решение ) : Просто используйте это:

recyclerView.setSaveEnabled(false);

Ответы [ 2 ]

1 голос
/ 15 февраля 2020

Если вы отсоедините и снова прикрепите фрагмент, то только его иерархия просмотра будет уничтожена и воссоздана. Восстановление позиции прокрутки является частью поведения восстановления состояния RecyclerView.

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

recyclerView.setSaveEnabled(false);
0 голосов
/ 14 февраля 2020

Да Android сохранено автоматически сохраняет старый ViewHolder для более эффективного использования памяти.

Если вам не нужно.

Затем снова установите адаптер или выполните notifyDataSetChanged ();

...