Что такое PageStorage в Flutter?

Ответ

PageStorage — это виджет и сопутствующая система в Flutter для сохранения и восстановления состояния (например, позиции скролла) виджетов, которые временно удаляются из дерева, обычно при навигации между страницами (Route).

Как это работает:

  1. PageStorage (чаще всего PageStorageBucket) предоставляется выше в дереве виджетов, обычно MaterialApp или WidgetsApp делают это автоматически.
  2. Виджет, состояние которого нужно сохранить (например, ListView), получает PageStorageKey.
  3. При удалении виджета (например, переход на другой экран) его состояние (например, ScrollPosition) сохраняется в PageStorageBucket, ассоциированном с ключом.
  4. При повторном создании виджета с тем же ключом состояние восстанавливается.

Практический пример — сохранение позиции скролла в ListView:

ListView.builder(
  key: const PageStorageKey<String>('products_list'), // Уникальный ключ для этого списка
  itemCount: 100,
  itemBuilder: (context, index) => ListTile(title: Text('Item $index')),
)

Где это полезно:

  • В TabBarView, где каждая вкладка — отдельный скроллящийся список.
  • При навигации Navigator.push и возврате Navigator.pop.
  • В сложных виджетах с внутренним состоянием, которое дорого пересчитывать.

Важно: PageStorage не предназначен для постоянного хранения данных (для этого используйте shared_preferences или базу данных). Он управляет временным состоянием в рамках сессии работы с приложением.

Ответ 18+ 🔞

А, ну это же та самая штука, которая не даёт твоему скроллу слетать в ноль, когда ты переходишь на другую страницу и обратно! Ёпта, сколько раз бывало — листаешь ленту, уходишь в детали, возвращаешься, а тебя опять на самый верх выкидывает, будто ничего и не было. Чистый пиздец, волнение ебать, терпения ноль.

Так вот, PageStorage — это как раз та хитрая жопа во флаттере, которая эту проблему решает. Представь себе ящик с ячейками (это PageStorageBucket), который висит где-то высоко в дереве виджетов, обычно в самом MaterialApp. И когда ты уходишь с экрана, и твой ListView начинают демонтировать, эта система быстренько выковыривает из него текущее состояние скролла (или что там ещё) и пихает в ячейку, подписанную уникальным ключом. А когда ты возвращаешься, и виджет создаётся заново, она достаёт сохранённое состояние из той же ячейки и говорит: «На, мудила, вот твоя прошлая позиция, скролль обратно».

Как это прикрутить на практике, чтобы скролл не сбрасывался:

ListView.builder(
  key: const PageStorageKey<String>('my_awesome_list'), // Вот этот самый волшебный ключ! Название придумай своё.
  itemCount: 100,
  itemBuilder: (context, index) => ListTile(title: Text('Элемент $index')),
)

Всё, блядь! Главное — не забудь этот PageStorageKey. Без него система не поймёт, куда что сохранять и откуда восстанавливать. Это как сейф в отеле: номер ключа должен совпадать, иначе откроешь не свою шкатулку.

Где эта фигня реально спасает жизнь:

  • В этих ваших TabBarView, где под каждой вкладкой свой бесконечный список новостей или товаров. Без PageStorage переключил вкладку — вернулся — а скролл обнулился. Удивление пиздец, каждый раз заново скроллить.
  • При обычной навигации туда-сюда между экранами. Ушёл в детали товара, вернулся в каталог — и продолжаешь с того же места.
  • Во всяких сложных виджетах, состояние которых овердохуища ресурсов стоит пересчитывать.

Но запомни раз и навсегда, чувак: это НЕ для постоянного хранения данных! Не вздумай сюда пароли или настройки пихать. PageStorage живёт ровно до тех пор, пока живёт твоё приложение. Закрыл — всё, медным тазом накрылось. Для долгосрочного хранения есть shared_preferences, базы и прочая скучная хуйня.

Короче, инструмент простой, но офигенно полезный. Поставил ключ — и забыл про проблему.