【Flutter】infinite_scroll_paginationでスクロールを拡張

Flutter

infinite_scroll_paginationとは

infinite_scroll_paginationは、ユーザーが画面をスクロールするにつれて小さなアイテムのチャンクを遅延ロードおよび表示するための、意見を持たず、拡張性が高く、カスタマイズ可能なパッケージです。
エンドレススクロール、オートページネーション、レイジーロードなど、さまざまなページネーション戦略を簡単に実装できます。

infinite_scroll_pagination | Flutter package
Lazily load and display pages of items as the user scrolls down your screen.

使い方

1. インストール

pubspec.yamlファイルに以下の依存関係を追加します:

dependencies:
  flutter:
    sdk: flutter
  infinite_scroll_pagination: ^4.0.0

2. 基本的な使用法

ページネーションコントローラーの設定

ページネーションを管理するためにPagingControllerを使用します。初期設定として、initStateでページリクエストリスナーを追加します:

import 'package:flutter/material.dart';
import 'package:infinite_scroll_pagination/infinite_scroll_pagination.dart';

class BeerListView extends StatefulWidget {
  @override
  _BeerListViewState createState() => _BeerListViewState();
}

class _BeerListViewState extends State<BeerListView> {
  static const _pageSize = 20;

  final PagingController<int, BeerSummary> _pagingController =
      PagingController(firstPageKey: 0);

  @override
  void initState() {
    _pagingController.addPageRequestListener((pageKey) {
      _fetchPage(pageKey);
    });
    super.initState();
  }

  Future<void> _fetchPage(int pageKey) async {
    try {
      final newItems = await RemoteApi.getBeerList(pageKey, _pageSize);
      final isLastPage = newItems.length < _pageSize;
      if (isLastPage) {
        _pagingController.appendLastPage(newItems);
      } else {
        final nextPageKey = pageKey + newItems.length;
        _pagingController.appendPage(newItems, nextPageKey);
      }
    } catch (error) {
      _pagingController.error = error;
    }
  }

  @override
  Widget build(BuildContext context) => PagedListView<int, BeerSummary>(
        pagingController: _pagingController,
        builderDelegate: PagedChildBuilderDelegate<BeerSummary>(
          itemBuilder: (context, item, index) => BeerListItem(
            beer: item,
          ),
        ),
      );

  @override
  void dispose() {
    _pagingController.dispose();
    super.dispose();
  }
}

APIコールのカスタマイズ

APIの呼び出しは完全にカスタマイズ可能です。自分のAPIやデータ取得戦略に合わせて_fetchPageメソッドを実装します。

Future<void> _fetchPage(int pageKey) async {
  try {
    final newItems = await RemoteApi.getBeerList(pageKey, _pageSize);
    final isLastPage = newItems.length < _pageSize;
    if (isLastPage) {
      _pagingController.appendLastPage(newItems);
    } else {
      final nextPageKey = pageKey + newItems.length;
      _pagingController.appendPage(newItems, nextPageKey);
    }
  } catch (error) {
    _pagingController.error = error;
  }
}

3. カスタマイズ

カスタムインジケータ

デフォルトのプログレスインジケータやエラーインジケータをカスタマイズする場合は、PagedChildBuilderDelegateのプロパティを利用します:

PagedListView<int, BeerSummary>(
  pagingController: _pagingController,
  builderDelegate: PagedChildBuilderDelegate<BeerSummary>(
    itemBuilder: (context, item, index) => BeerListItem(beer: item),
    newPageProgressIndicatorBuilder: (context) => CircularProgressIndicator(),
    firstPageProgressIndicatorBuilder: (context) => CircularProgressIndicator(),
    noItemsFoundIndicatorBuilder: (context) => Text('No items found'),
    newPageErrorIndicatorBuilder: (context) => Text('Something went wrong'),
  ),
);

他のレイアウトとの統合

このパッケージは、ListViewGridViewだけでなく、カスタムレイアウトでも使用できます。以下のように、PagedSliverListPagedGridViewも利用できます:

PagedSliverList<int, BeerSummary>(
  pagingController: _pagingController,
  builderDelegate: PagedChildBuilderDelegate<BeerSummary>(
    itemBuilder: (context, item, index) => BeerListItem(beer: item),
  ),
);

4. 拡張性

プルツーリフレッシュの統合

Pull-to-Refresh機能をシームレスに統合することができます:

@override
Widget build(BuildContext context) => RefreshIndicator(
  onRefresh: () => Future.sync(
    () => _pagingController.refresh(),
  ),
  child: PagedListView<int, BeerSummary>(
    pagingController: _pagingController,
    builderDelegate: PagedChildBuilderDelegate<BeerSummary>(
      itemBuilder: (context, item, index) => BeerListItem(beer: item),
    ),
  ),
);

Buy me a coffee!

Flutterアプリ開発
シェアする
sogaをフォローする
タイトルとURLをコピーしました