Navigation

Pagination

Display the current active page and enable navigation between multiple pages.

1@override
2Widget build(BuildContext context) =>
3 const FPagination(control: .managed(pages: 10));
4

CLI

To generate and customize this style:

dart run forui style create pagination

Usage

FPagination(...)

1FPagination(
2 style: .delta(itemPadding: .symmetric(horizontal: 2)),
3 previous: Icon(FIcons.chevronLeft),
4 next: Icon(FIcons.chevronRight),
5)

Examples

Siblings

1@override
2Widget build(BuildContext context) => const FPagination(
3 control: .managed(
4 pages: 20,
5 siblings: 2,
6 initial: 9,
7 ),
8);
9

Hide Edges

1@override
2Widget build(BuildContext context) => const FPagination(
3 control: .managed(
4 pages: 8,
5 showEdges: false,
6 ),
7);
8

Custom Icons

1class PaginationCustomIconExample extends StatefulWidget {
2 @override
3 State<PaginationCustomIconExample> createState() =>
4 _PaginationCustomIconExampleState();
5}
6
7class _PaginationCustomIconExampleState
8 extends State<PaginationCustomIconExample> {
9 late final _controller = FPaginationController(pages: 10, page: 4);
10
11 @override
12 void dispose() {
13 _controller.dispose();
14 super.dispose();
15 }
16
17 @override
18 Widget build(BuildContext context) {
19 final style = context.theme.paginationStyle;
20 return FPagination(
21 control: .managed(controller: _controller),
22 next: Padding(
23 padding: style.itemPadding,
24 child: ConstrainedBox(
25 constraints: style.itemConstraints,
26 child: FButton.icon(
27 variants: {.ghost},
28 onPress: _controller.next,
29 child: IconTheme(
30 data: style.itemIconStyle.resolve({}),
31 child: const Icon(FIcons.bird),
32 ),
33 ),
34 ),
35 ),
36 previous: Padding(
37 padding: style.itemPadding,
38 child: ConstrainedBox(
39 constraints: style.itemConstraints,
40 child: FButton.icon(
41 variants: {.ghost},
42 onPress: _controller.previous,
43 child: IconTheme(
44 data: style.itemIconStyle.resolve({}),
45 child: const Icon(FIcons.anchor),
46 ),
47 ),
48 ),
49 ),
50 );
51 }
52}
53

With a PageView

1class PaginationWithViewExample extends StatefulWidget {
2 @override
3 State<PaginationWithViewExample> createState() =>
4 _PaginationWithViewExampleState();
5}
6
7class _PaginationWithViewExampleState extends State<PaginationWithViewExample> {
8 final _controller = PageController();
9 final _paginationController = FPaginationController(pages: 10);
10
11 @override
12 void didChangeDependencies() {
13 super.didChangeDependencies();
14 _paginationController.value =
15 PageStorage.maybeOf(context)?.readState(context) ?? 0;
16 }
17
18 void _handlePageChange(int page) {
19 final old = _controller.page?.round();
20 if (old case final old when old != page) {
21 if (page == old! + 1 || page == old - 1) {
22 setState(() {
23 _controller.animateToPage(
24 page,
25 duration: const Duration(milliseconds: 300),
26 curve: Curves.easeInOut,
27 );
28 });
29 } else {
30 setState(() {
31 _controller.jumpToPage(page);
32 });
33 }
34 }
35 }
36
37 @override
38 void dispose() {
39 _paginationController.dispose();
40 _controller.dispose();
41 super.dispose();
42 }
43
44 @override
45 Widget build(BuildContext context) {
46 final colors = context.theme.colors;
47 return Column(
48 mainAxisSize: .min,
49 mainAxisAlignment: .center,
50 spacing: 10,
51 children: [
52 SizedBox(
53 height: 300,
54 width: 300,
55 child: NotificationListener<ScrollEndNotification>(
56 onNotification: (notification) {
57 if (_controller.hasClients) {
58 _paginationController.value = _controller.page!.round();
59 return true;
60 }
61
62 return false;
63 },
64 child: PageView.builder(
65 itemCount: 10,
66 controller: _controller,
67 itemBuilder: (context, index) => ColoredBox(
68 color: index.isEven
69 ? colors.hover(colors.primary)
70 : colors.mutedForeground,
71 child: Center(
72 child: DefaultTextStyle(
73 style: TextStyle(
74 fontSize: 45,
75 color: colors.primaryForeground,
76 ),
77 child: Text('Page ${index + 1}'),
78 ),
79 ),
80 ),
81 ),
82 ),
83 ),
84 FPagination(
85 control: .managed(
86 controller: _paginationController,
87 onChange: _handlePageChange,
88 ),
89 ),
90 ],
91 );
92 }
93}
94

On this page