まずはdartレベルでページング処理を作成
こんな感じのページネーションをflutter webで作ることになりました。
無限スクロールのパッケージはたくさんありますが、上記の様なオーソドックスなパターンのは見当たらなかったので、自作します。
ソース
基本はgoogleのページネーションを参考にしています。
import 'dart:math'; class Pagination { // 一度に画面に表示できる最大のページ数 static const max = 10; static int maxHalf() => (max / 2).floor(); static int centerLeftDiff() => maxHalf() - 1; static List<int> pagination(int selectedPage, int pageMax) { if (pageMax < selectedPage) { throw Exception('selectedPage must be less than or equal to pageMax'); } // 右の最大ページが決まれば1に到達するか10個までカウントする List<int> pagination = []; for (var i = rightMaxNumber(selectedPage, pageMax); i > 0; i--) { if (pagination.length == max) { break; } pagination.add(i); } // for文の条件を反転させればreverseしなくてもいいと思うが // そうなると最小値を求めないといけなくなる return pagination.reversed.toList(); } static int rightMaxNumber(int selectedPage, int pageMax) { int rightMaxNumber = 0; // 今回の例で言うと6ページを境に動作が変わる if (selectedPage <= maxHalf() + 1) { rightMaxNumber = min(pageMax, max); } else { rightMaxNumber = min(selectedPage + maxHalf() - 1, pageMax); } return rightMaxNumber; } }
テストコード
import 'package:flutter_test/flutter_test.dart'; import 'package:flutter2_practice/src/pagination/pagination.dart'; void main() { group('Pagination', () { test('rightMaxNumber', () { expect(Pagination.rightMaxNumber(1, 1), 1); expect(Pagination.rightMaxNumber(1, 10), 10); expect(Pagination.rightMaxNumber(1, 11), 10); expect(Pagination.rightMaxNumber(6, 6), 6); expect(Pagination.rightMaxNumber(6, 7), 7); expect(Pagination.rightMaxNumber(6, 10), 10); expect(Pagination.rightMaxNumber(6, 11), 10); expect(Pagination.rightMaxNumber(7, 7), 7); expect(Pagination.rightMaxNumber(7, 8), 8); expect(Pagination.rightMaxNumber(7, 10), 10); expect(Pagination.rightMaxNumber(7, 11), 11); expect(Pagination.rightMaxNumber(7, 100), 11); }); test('pagination', () { expect(Pagination.pagination(1, 1), [1]); expect(Pagination.pagination(1, 3), [1, 2, 3]); expect(Pagination.pagination(1, 10), [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]); expect(Pagination.pagination(1, 11), [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]); expect(Pagination.pagination(6, 6), [1, 2, 3, 4, 5, 6]); expect(Pagination.pagination(6, 7), [1, 2, 3, 4, 5, 6, 7]); expect(Pagination.pagination(6, 10), [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]); expect(Pagination.pagination(6, 11), [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]); expect(Pagination.pagination(7, 7), [1, 2, 3, 4, 5, 6, 7]); expect(Pagination.pagination(7, 8), [1, 2, 3, 4, 5, 6, 7, 8]); expect(Pagination.pagination(7, 10), [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]); expect(Pagination.pagination(7, 11), [2, 3, 4, 5, 6, 7, 8, 9, 10, 11]); expect(Pagination.pagination(7, 12), [2, 3, 4, 5, 6, 7, 8, 9, 10, 11]); expect(Pagination.pagination(7, 100), [2, 3, 4, 5, 6, 7, 8, 9, 10, 11]); expect(Pagination.pagination(14, 20), [9, 10, 11, 12, 13, 14, 15, 16, 17, 18]); }); }); }
上記のソースコードと、それをwidgetに組み込んだものも下記にあります。一番上の画像のようにはまだなってません。
https://github.com/na8esin/flutter2_practice/blob/main/lib/src/pagination