Flutter 3.13: làm Sticky Header dễ dàng với SliverMainAxisGroup
I. Mở đầu
Mới đây Flutter 3.13 mới ra mắt, mang đến nhiều sự nâng cấp cũng như cải thiện đáng kể như render engine Impeller
cho iOS, support foldable, dialog + Material widgetS,…và cho ra mắt 1 vài widget sliver hữu ích như SliverMainAxisGroup
, SliverCrossAxisGroup
,…Đối với SliverMainAxisGroup
, chắc chắc lập trình viên sẽ tiết kiệm nhiều thời gian trong việc viết sticky header animation để tăng trải nghiệm người dùng.
2. SliverMainAxisGroup
Cho những ai chưa biết thì, để hiển thị UI dạng scroll list thì ngoài ListView
, Flutter còn cung cấp CustomScrollView
- cho phép hiển thị list content cũng như scroll animation phức tạp trên scroll list.
Các widget con của CustomScrollView
được gọi là sliver và có prefix Sliver
ở tên class. Ví dụ:
SliverPadding ~ Padding
SliverList ~ ListView
SliverBoxToAdapter ~ Single Widget
SliverAppBar ~ AppBar
SliverGrid ~ GridView
Và giờ đây chúng ta có SliverMainAxisGroup
- sliver này sắp xếp 1 nhóm widget con tuần tự theo 1 chiều dọc, bạn có thể hiểu nó tương tự như Column
.
3. Sticky header animation
Ok, bây giờ chúng ta hãy tiến hành thực hiện sticky header animation. Như ở gif demo, chúng
ta thấy sẽ có nhiều header và các item đi theo từng header, mình sẽ gọi group 1 header và các item như vậy là 1 section. Như vậy, mình sẽ viết 1 class widget cho section, sử dụng SliverMainAxisGroup
chứa SliverAppBar
và SliverList
.
SliverAppBar
được sử dụng cho header, và có thuộc tínhpinned: true
nhằm khi scroll các item thì header sẽ pin ở trên đầuCustomScrollView
, khi các item bị scroll hết đi, header mới đc scroll theo.SliverList
được sử dụng để hiển thị item đi theo header.
class SectionWidget extends StatelessWidget {
final String header;
final Widget Function(BuildContext, int) itemBuilder;
final int itemCount;
const SectionWidget(
{super.key,
required this.header,
required this.itemBuilder,
required this.itemCount});
@override
Widget build(BuildContext context) {
return SliverMainAxisGroup(
slivers: <Widget>[
SliverAppBar(
title: Text(
header,
style: const TextStyle(color: Colors.black),
),
expandedHeight: 70.0,
backgroundColor: Colors.white,
elevation: 0.0,
pinned: true,
),
SliverList.builder(
itemBuilder: itemBuilder,
itemCount: itemCount,
),
],
);
}
}
Tiếp theo, chúng ta sẽ tạo vài section và hiển thị chúng lên CustomScrollView
.
class SliverMainAxisGroupExample extends StatelessWidget {
const SliverMainAxisGroupExample({super.key});
@override
Widget build(BuildContext context) {
return CustomScrollView(
slivers: <Widget>[
SectionWidget(
header: 'Header 1',
itemBuilder: (context, index) {
return Container(
color: index.isEven ? Colors.amber[300] : Colors.blue[300],
height: 100,
padding: const EdgeInsets.all(16),
child:
Text('Item $index', style: const TextStyle(fontSize: 20)),
);
},
itemCount: 10),
SectionWidget(
header: 'Header 2',
itemBuilder: (context, index) {
return Container(
color: index.isEven ? Colors.amber[300] : Colors.blue[300],
height: 100,
padding: const EdgeInsets.all(16),
child:
Text('Item $index', style: const TextStyle(fontSize: 20)),
);
},
itemCount: 10),
],
);
}
}
Kết quả:
4. Lời Kết
Với phiên bản Flutter 3.13 và class SliverMainAxisGroup
, việc thực hiện sticky header animation trở nên dễ dàng hơn bao giờ hết. Đây là một trong những ví dụ cho việc đội ngũ và cộng đồng Flutter đang cố gắng như thế nào để thúc đẩy Flutter trở nên trưởng thành và toàn diện hơn; mang đến trải nghiệm lập trình thú vị và tuyệt vời; giúp lập trình viên tạo ra các ứng dụng chất lượng hơn. Hãy cùng mình chờ xem những tính năng thú vị nào sẽ xuất hiện ở những phiên bản Flutter trong tương lai nhé.