Что такое Slivers во Flutter и когда их использовать?
Комментарии (2)
Ответ сгенерирован нейросетью и может содержать ошибки
Slivers во Flutter: мощный инструмент для прокрутки
Что такое Slivers?
Sliver (лоскут, полоса) — это подвижный фрагмент пространства прокрутки в Flutter. Это низкоуровневая абстракция для создания сложных и эффективных эффектов прокрутки.
Проще говоря, Sliver — это виджет, который осознаёт скроллинг и может меняться при прокрутке (изменять размер, исчезать, появляться и т.д.).
Стандартные Slivers
// CustomScrollView — контейнер для slivers
CustomScrollView(
slivers: [
// SliverAppBar — меняется при прокрутке
SliverAppBar(
expandedHeight: 200,
floating: false,
pinned: true, // Остаётся в т.ч. при прокрутке
flexibleSpace: FlexibleSpaceBar(
title: Text("Profile"),
background: Image.network(url),
),
),
// SliverList — список с прокруткой
SliverList(
delegate: SliverChildBuilderDelegate(
(context, index) => ListTile(
title: Text("Item $index"),
),
childCount: 50,
),
),
// SliverGrid — сетка с прокруткой
SliverGrid(
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 2,
mainAxisSpacing: 10,
crossAxisSpacing: 10,
),
delegate: SliverChildBuilderDelegate(
(context, index) => Container(
color: Colors.blue,
child: Center(child: Text("$index")),
),
childCount: 20,
),
),
// SliverToBoxAdapter — обычный виджет в прокрутке
SliverToBoxAdapter(
child: Container(
height: 100,
color: Colors.green,
child: Center(child: Text("Custom Widget")),
),
),
],
)
Когда использовать Slivers?
Используйте Slivers, когда нужны:
-
Сложные заголовки — которые меняются при прокрутке
- Свёртывающийся AppBar
- Параллакс-эффект
- Закрепление заголовка
-
Несколько скроллируемых элементов в одной полоске прокрутки
- Список + сетка + текст в одном скроллвью
- Множественные коллекции в одной прокрутке
-
Пользовательские эффекты прокрутки
- Снап-эффекты
- Фильтры, которые исчезают при прокрутке
- Любые анимации, зависящие от позиции скролла
Пример: профиль пользователя с несколькими коллекциями
class UserProfilePage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return CustomScrollView(
slivers: [
// Заголовок профиля
SliverAppBar(
expandedHeight: 250,
pinned: true,
flexibleSpace: FlexibleSpaceBar(
title: Text("John Doe"),
background: Stack(
fit: StackFit.expand,
children: [
Image.network(
"https://example.com/profile.jpg",
fit: BoxFit.cover,
),
Container(
decoration: BoxDecoration(
gradient: LinearGradient(
begin: Alignment.topCenter,
end: Alignment.bottomCenter,
colors: [Colors.transparent, Colors.black],
),
),
),
],
),
),
),
// Информация о пользователе
SliverToBoxAdapter(
child: Padding(
padding: EdgeInsets.all(16),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
"Followers: 1.2K",
style: TextStyle(fontSize: 16, fontWeight: FontWeight.bold),
),
SizedBox(height: 8),
Text("Software Engineer"),
],
),
),
),
// Посты (список)
SliverToBoxAdapter(
child: Padding(
padding: EdgeInsets.symmetric(horizontal: 16),
child: Text(
"Posts",
style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold),
),
),
),
SliverList(
delegate: SliverChildBuilderDelegate(
(context, index) => ListTile(
title: Text("Post ${index + 1}"),
subtitle: Text("2 hours ago"),
),
childCount: 10,
),
),
// Галерея (сетка)
SliverToBoxAdapter(
child: Padding(
padding: EdgeInsets.symmetric(horizontal: 16, vertical: 16),
child: Text(
"Gallery",
style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold),
),
),
),
SliverGrid(
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 3,
mainAxisSpacing: 8,
crossAxisSpacing: 8,
),
delegate: SliverChildBuilderDelegate(
(context, index) => Container(
color: Colors.grey[300],
child: Center(child: Text("$index")),
),
childCount: 15,
),
),
],
);
}
}
Параллакс-эффект с Slivers
SliverAppBar(
expandedHeight: 300,
flexibleSpace: FlexibleSpaceBar(
title: Text("Parallax"),
background: Stack(
fit: StackFit.expand,
children: [
// Фоновое изображение с параллаксом
FlexibleSpaceBar.createSettings(
minExtent: 56,
maxExtent: 300,
currentExtent: 300,
child: Image.network(
"url",
fit: BoxFit.cover,
),
),
],
),
),
)
Производительность
Slivers эффективны, потому что:
- Рендерят только видимые элементы (как ListView)
- Позволяют комбинировать разные типы контента в одной прокрутке
- Минимизируют пересчёты при скроллинге
- Поддерживают слои (layering) для сложных эффектов
Когда NOT использовать Slivers?
- Простые списки → используйте ListView
- Простые сетки → используйте GridView
- Нет надобности в совмещении разных типов контента
Итог
Slivers — это мощный инструмент для создания сложных интерфейсов с интерактивной прокруткой. Используйте их для профилей, чатов с несколькими типами сообщений, маркетплейсов с комбинированным контентом. Но помните: для простых случаев лучше использовать ListView/GridView.