Задать вопрос
coder1cv8
@coder1cv8
Инди-разработчик

Как сохранить состояние RecyclerView?

Постараюсь объяснить максимально подробно. Есть 2 фрагмента, в первом находится RecyclerView. Его элементы добавляются из REST-сервиса, пачками, постранично. То есть, создали фрагмент, подгрузили первые 20 элементов, юзер скроллит список, доходит до конца, тут подгружаются следующие 20 элементов и тд. Такой паттерн гуглится по "endless recyclerview".

По нажатию на элемент списка переходим на второй фрагмент:

Fragment product = new FragmentProduct();

Bundle bundle = new Bundle();
bundle.putString("PRODUCT", new Gson().toJson(mProductsAdapter.getItem(position)));
product.setArguments(bundle);

getActivity()
	.getSupportFragmentManager()
	.beginTransaction()
	.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN)
	.replace(R.id.frame_container, product)
	.addToBackStack(null)
	.commit();

Обычное такое поведение, из списка продуктов открываем детальную информацию о выбранном продукте. Так вот, как при нажатии юзером кнопки Back получить такое же состояние RecyclerView? Ведь первый фрагмент (со списком) уничтожается когда открывается второй (с детальной информацией об элементе списка)? Для первого фрагмента вызывается onDestroyView(), потом onCreateView() и RecyclerView заполняется заново. Тянуть из REST-сервиса все страницы которые успел проскроллить пользователь? - не вариант.

У меня есть 2 идеи:

1. Кэшировать элементы списка (сохранять их в БД) и когда возвращаемся на первый фрагмент со списком - читать из кэша, а не из сервиса.

2. Отказаться от использования фрагмента для детальной информации о продукте. Показывать ее в каком-нибудь диалоге, тогда фрагмент со списком ведь не будет уничтожаться?

Но все это как-то криво, я наверное, упустил какую-то базовую вещь по работе с фрагментами... Как обычно решают такую задачу?

Update: Надо наверное, еще отметить отдельно, что с сохранением положения скролла - проблем нет, вопрос именно в сохранении содержимого при открытии "дочернего" фрагмента.
  • Вопрос задан
  • 2315 просмотров
Подписаться 3 Оценить Комментировать
Решения вопроса 1
@FoxInSox
Кешировать надо. Пользователь может уйти из приложения кнопкой home, и вернуться спустя несколько часов где-нибудь в метро, где нет интеренета, и тогда без кеширования ваше приложение будет бесполещно. Ну и это странно перезагружать данные которые уже были загружены однажды.

Для первого фрагмента вызывается onDestroyView(), потом onCreateView() и RecyclerView заполняется заново.

Он не сам заполняется, вы его заполняете. Ссылку на созданный адаптер(с загруженными данными) можно хранить в фрагменте. И в методе onCreateView использовать снова этот адаптер.
Ответ написан
Пригласить эксперта
Ответы на вопрос 1
@poserge
Все нижеследующее из головы, так что могут быть неточности:
Состояние фрагментов, так же как и активити, можно сохранять в методе onSaveInstanceState и восстанавливать его при новом запуске. Тонкость в том, что это должен быть фрагмент с тем же ID, иначе onCreate() не "увидит" сохраненное состояние, и ID это не задается вручную. Потому фрагменты не надо явно уничтожать и при повторном создании надо проверять их наличие с помощью findFragmentByTag().
Вообще фрагменты довольно живучи, их система пересоздает даже если активити была уничтожена и запущена заново, так что я бы рекомендовал попробовать сохранить состояние в onSaveInstanceState и восстановить в onCreate().
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы