Ответ
PageStorageKey — это специальный тип ValueKey, который используется в паре с виджетом PageStorage для идентификации и сохранения состояния конкретного виджета (чаще всего позиции скролла).
Назначение: Связывает состояние виджета (данные) с уникальным идентификатором в PageStorageBucket. Это позволяет Flutter понять, какое состояние принадлежит какому виджету, особенно когда виджет уничтожается и создается заново.
Синтаксис и использование:
// Для простых случаев можно использовать строку
const PageStorageKey<String>('my_unique_list_key')
// Или любой другой comparable-объект в качестве значения
PageStorageKey<int>(42)
PageStorageKey<MyClass>(myInstance) // где MyClass реализует == и hashCode
Типичный сценарий применения со Scrollable виджетами:
CustomScrollView(
key: const PageStorageKey('home_feed_scroll'),
slivers: [
SliverList(...),
],
)
// При возврате на этот экран позиция скролла восстановится автоматически.
Ключевые моменты:
- Уникальность: Ключ должен быть уникальным в рамках одного
PageStorageBucket(обычно в рамках одного маршрута/Route) для разных сохраняемых виджетов. Иначе состояния могут перепутаться. - Типизация: Использование дженерика (
PageStorageKey<T>) помогает избежать случайных коллизий ключей разных типов. - Не для всех виджетов: В основном используется со
ListView,GridView,CustomScrollViewи другими прокручиваемыми виджетами, но может применяться и для сохранения другого простого состояния.
Без PageStorageKey скроллящиеся виджеты при повторной инициализации начинали бы с позиции 0.0.
Ответ 18+ 🔞
Да ты посмотри, какая хитрая штука этот PageStorageKey! Ну в общем, представляешь, это такой специальный пацан из семейства ValueKey, который работает заодно с виджетом PageStorage. Их главная фишка — они как будто вешают бирочку на состояние какого-нибудь виджета (ну, чаще всего на позицию скролла, конечно) и прячут эту бирочку в специальное ведро — PageStorageBucket. А потом, когда виджет нахуй сносит и собирают заново, Flutter смотрит в это ведро, находит по бирочке сохранённые данные и говорит: «А, так это ж твои, на, держи!». Без этого всё начиналось бы с нуля каждый раз, ёпта.
Как этим пользоваться, чтобы не облажаться:
// Можно просто строку впихнуть, главное, чтобы уникальная была
const PageStorageKey<String>('ключ_от_моей_длиннющей_ленты')
// Или вообще что угодно, что можно сравнивать (comparable)
PageStorageKey<int>(42)
PageStorageKey<MyClass>(myInstance) // если в MyClass == и hashCode прописаны
Где это обычно впендюривают (прям классика):
CustomScrollView(
key: const PageStorageKey('home_feed_scroll'), // Вот она, волшебная палочка!
slivers: [
SliverList(...),
],
)
// Ушёл с экрана, вернулся — а скролл на том же месте, где и был! Магия, блядь.
А теперь главное, что надо помнить, а то будет пиздец:
- Уникальность — наше всё: Ключ должен быть как отпечаток пальца в рамках одного
PageStorageBucket(это обычно один маршрут). Если для двух разных списков сделать одинаковый ключ — они начнут делить одно состояние, и получится ебанько полная. Один будет скроллиться, а второй за ним повторять. - Типизация — не просто так: Дженерик (
PageStorageKey<T>) — это не для красоты. Он помогает, чтобы ключ-строка случайно не сцепился с ключом-числом, если они одинаково выглядят. Удивление пиздец будет, когда всё сломается. - Не только для скролла: Да, чаще всего его цепляют на
ListView,GridView,CustomScrollView, чтобы позицию не терять. Но вообще-то можно и любое другое простое состояние виджета сохранять, если очень захотеть.
Короче, без этого PageStorageKey твой скролл каждый раз как новорождённый — начинает жизнь с самого верха, с позиции 0.0. А так — всё помнит, хитрая жопа. Главное, ключи не перепутай, а то вместо ленты новостей будешь восстанавливать позицию в настройках, ядрёна вошь.