Ответ
PageStorage — это виджет и сопутствующая система в Flutter для сохранения и восстановления состояния (например, позиции скролла) виджетов, которые временно удаляются из дерева, обычно при навигации между страницами (Route).
Как это работает:
PageStorage(чаще всегоPageStorageBucket) предоставляется выше в дереве виджетов, обычноMaterialAppилиWidgetsAppделают это автоматически.- Виджет, состояние которого нужно сохранить (например,
ListView), получаетPageStorageKey. - При удалении виджета (например, переход на другой экран) его состояние (например,
ScrollPosition) сохраняется вPageStorageBucket, ассоциированном с ключом. - При повторном создании виджета с тем же ключом состояние восстанавливается.
Практический пример — сохранение позиции скролла в 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, базы и прочая скучная хуйня.
Короче, инструмент простой, но офигенно полезный. Поставил ключ — и забыл про проблему.