Всё о Slivers и немного больше. Часть 1
Всем привет! На связи Арсен, Flutter-разработчик Mad Brains. Многие из вас наверняка уже знакомы с Slivers, ведь это мощный инструмент для создания динамичных и адаптивных прокручиваемых областей в приложениях Flutter. В этом цикле статей рассмотрим все существующие sliver-виджеты во Flutter, чтобы познакомиться с каждым из них, понять, какие задачи они решают, и как их можно применять. Мы не будем углубляться в детали, дабы не усложнять материал, а обозначим основные особенности и отличия каждого сливера, чтобы понимать, какие вообще существуют и в нужный момент воспользоваться ими. Итак, погнали!
Тест на Flutter-разработчика: думскролинг или sliver?
Для начала немного общей информации о скролле.
ScrollView — виджет, который объединяет Scrollable и Viewport для создания интерактивной области прокрутки содержимого.
Scrollable — виджет, который с помощью распознавания жестов, управляет прокруткой и информирует Viewport.
Viewport — виджет, с помощью которого можно просматривать часть более крупного содержимого. Дочерние объекты для Viewport — Slivers.
Эта компания находиться под капотом у всех прокручиваемых виджетов, в том числе и у классического ListView. Рассмотрим все виды сливеров, а начнем как раз со списков.
SliverList
Пример работы SliverList.
SliverList — размещает множество элементов в линейном массиве вдоль главной оси, то есть отображает список элементов.
SliverList(
delegate: SliverChildListDelegate(items),
),
Несколько сливеров, которые делают тоже самое, что и SliverList, но с нюансом:
SliverFixedExtentList — отличается тем, что размер дочерних элементов по главной оси равен заданному значению.
SliverFixedExtentList(
itemExtent: 100.0,
delegate: SliverChildListDelegate(items),
),
SliverPrototypeExtentList — тут размер по главной оси уже задается виджетом-прототипом, удобно, когда высота элементов может меняться в зависимости от контента, но при этом остается одинаковой для всех элементов.
SliverPrototypeExtentList(
prototypeItem: someWidget,
delegate: SliverChildListDelegate(items),
),
SliverVariedExtentList —, а тут размер определяется по правилу, возвращаемому полем itemExtentBuilder. Сливер более эффективен, чем SliverList, потому что не нужно размещать дочерние элементы, чтобы получить их протяженность вдоль главной оси и более гибкий, чем SliverFixedExtentList (или SliverPrototypeExtentList), потому что позволяет дочерним элементам иметь разные размеры. SliverLayoutDimensions — объект, предоставляющий информацию о текущих размерах видимой области, в которой находится SliverVariedExtentList.
SliverVariedExtentList(
itemExtentBuilder: (int index, SliverLayoutDimensions dimensions) {
return (index + 1) * 3 + 40;
},
delegate: SliverChildListDelegate(items),
),
SliverReorderableList
Пример работы SliverReorderableList
SliverReorderableList — список, который позволяет пользователю интерактивно изменять порядок элементов, обычный ReorderableList использует именно этот сливер под капотом.
SliverReorderableList(
itemBuilder: (context, index) {
return ListTile(items[index]);
},
itemCount: items.length,
onReorder: (oldIndex, newIndex) {
setState(() {
if (newIndex > oldIndex) {
newIndex -= 1;
}
final item = items.removeAt(oldIndex);
items.insert(newIndex, item);
});
},
),
SliverAnimatedList
Пример работы SliverAnimatedList
SliverAnimatedList — SliverList, который анимирует элементы при их вставке или удалении. Для вставки или удаления элементов используется SliverAnimatedListState, чтобы к нему обратиться, либо укажите GlobalKey, либо используйте статический метод SliverAnimatedList.of.
final GlobalKey _listKey = GlobalKey();
...
SliverAnimatedList(
key: _listKey,
initialItemCount: items.length,
itemBuilder: (context, index, animation) {
return ListTile(items[index], animation);
},
),
SliverFillViewport
Пример работы SliverFillViewport
SliverFillViewport — немного выбивается от предыдущих сливеров, нет в названии слова List, однако в остальном очень похож, также получает делегат, предоставляющий дочерние элементы. Главная особенность — делает каждый элемент заполняющим область просмотра, степень заполнения можно регулировать параметром viewportFraction.
SliverFillViewport(
delegate: SliverChildListDelegate(items),
),
SliverGrid
Пример работы SliverGrid
SliverGrid — размещает дочерние элементы в двумерной компоновке. GridView реализован с помощью этого сливера.
SliverGrid(
gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 2,
),
delegate: SliverChildListDelegate(items),
),
SliverAnimatedGrid
Пример работы SliverAnimatedGrid
SliverAnimatedGrid — SliverGrid, который анимирует элементы при их вставке или удалении. Тут также, как и в случае SliverAnimatedList, для вставки и удаления используем SliverAnimatedGridState (через GlobalKey или SliverAnimatedGrid.of).
final GlobalKey _gridKey = GlobalKey();
...
SliverAnimatedGrid(
key: _gridKey,
initialItemCount: items.length,
gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 2,
),
itemBuilder: (context, index, animation) {
return GridTile(items[index], animation);
},
),
На этом всё, в следующей статье продолжим тему списков и поговорим об их делегатах. Пишите в комментариях, какими sliver-виджетами из перечисленных пользуетесь.