Flutter分页加载插件paging的使用

Flutter分页加载插件paging的使用

Installation(安装)

在您的项目pubspec.yaml文件中添加以下依赖:

dependencies:
  ...
  paging: ^latest.version.here

运行flutter pub get以获取依赖项。

Usage(使用)

首先导入paging.dart文件:

import 'package:paging/paging.dart';

Pagination小部件非常简单易用。您可以将类型<T>作为参数传递给小部件,默认情况下假定为dynamic

必需参数

  1. pageBuilder:需要一个返回Future<List<T>>的函数,并提供当前列表的大小。
  2. itemBuilder:需要一个返回Widget的函数,并提供要显示的类型<T>的项。

以下是完整的示例代码:

[@override](/user/override)
Widget build(BuildContext context) {
  return Scaffold(
    appBar: AppBar(title: Text('Pagination List')),
    body: Pagination<String>(
      pageBuilder: (currentSize) => pageData(currentSize),
      itemBuilder: (index, item) {
        return Container(
          color: Colors.yellow,
          height: 48,
          child: Text(item),
        );
      },
    ),
  );
}

示例代码解释

pageData 函数

模拟网络请求,每次加载更多数据:

// 模拟网络调用
Future<List<String>> pageData(int previousCount) async {
  // 模拟延迟
  await Future.delayed(Duration(seconds: 0, milliseconds: 2000));

  List<String> dummyList = [];

  // 停止加载数据,当计数达到30时
  if (previousCount < 30) {
    for (int i = previousCount; i < previousCount + _COUNT; i++) {
      dummyList.add('Item $i');
    }
  }

  return dummyList;
}

主页面代码

主页面中使用Pagination小部件:

class _MyHomePageState extends State<MyHomePage> {
  static const int _COUNT = 10;

  [@override](/user/override)
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text(widget.title)),
      body: Pagination(
        pageBuilder: (currentListSize) => pageData(currentListSize),
        itemBuilder: (index, item) => ListTile(title: Text(item)),
      ),
    );
  }
}

Screenshots(截图)

Getting Started(入门)

此项目是一个Dart包的起点,可以轻松地在多个Flutter或Dart项目中共享代码。

有关如何开始使用Flutter的更多信息,请参阅官方文档

完整示例代码

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

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  [@override](/user/override)
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.red,
      ),
      home: MyHomePage(title: 'Paging Example'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  MyHomePage({Key key, this.title}) : super(key: key);

  final String title;

  [@override](/user/override)
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  static const int _COUNT = 10;

  // 模拟网络调用
  Future<List<String>> pageData(int previousCount) async {
    await Future.delayed(Duration(seconds: 0, milliseconds: 2000));
    List<String> dummyList = [];

    if (previousCount < 30) {
      // 停止加载数据,当计数达到30时
      for (int i = previousCount; i < previousCount + _COUNT; i++) {
        dummyList.add('Item $i');
      }
    }

    return dummyList;
  }

  [@override](/user/override)
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text(widget.title)),
      body: Pagination(
        pageBuilder: (currentListSize) => pageData(currentListSize),
        itemBuilder: (index, item) => ListTile(title: Text(item)),
      ),
    );
  }
}

更多关于Flutter分页加载插件paging的使用的实战教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter分页加载插件paging的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


在Flutter中,paging 是一个用于实现分页加载的插件,它可以帮助你轻松地处理分页数据加载和显示。paging 插件通常与 ListViewGridView 结合使用,以便在用户滚动时自动加载更多数据。

1. 添加依赖

首先,你需要在 pubspec.yaml 文件中添加 paging 插件的依赖:

dependencies:
  flutter:
    sdk: flutter
  paging: ^3.0.0

然后运行 flutter pub get 来安装依赖。

2. 基本使用

2.1 创建 PagingController

PagingControllerpaging 插件的核心类,它负责管理分页数据的加载和状态。

import 'package:paging/paging.dart';

final PagingController<int, MyDataModel> _pagingController = PagingController(firstPageKey: 0);
  • int 是分页的键类型(通常是页码或偏移量)。
  • MyDataModel 是数据模型的类型。

2.2 实现 PagingSource

PagingSource 是一个抽象类,你需要实现它来定义如何从数据源加载数据。

class MyPagingSource extends PagingSource<int, MyDataModel> {
  [@override](/user/override)
  Future<LoadResult<int, MyDataModel>> load(LoadParams<int> params) async {
    try {
      final int pageKey = params.key ?? 0;
      final List<MyDataModel> data = await _fetchData(pageKey);

      final bool isLastPage = data.length < _pageSize;
      final int? nextPageKey = isLastPage ? null : pageKey + 1;

      return LoadResult.page(
        data: data,
        nextPageKey: nextPageKey,
      );
    } catch (e) {
      return LoadResult.error(e);
    }
  }

  Future<List<MyDataModel>> _fetchData(int pageKey) async {
    // 模拟从网络或数据库获取数据
    await Future.delayed(Duration(seconds: 1));
    return List.generate(10, (index) => MyDataModel(id: pageKey * 10 + index));
  }
}
  • load 方法负责加载数据,并返回 LoadResult
  • _fetchData 是一个模拟的异步方法,用于从数据源获取数据。

2.3 初始化 PagingController

initState 中初始化 PagingController 并设置 PagingSource

[@override](/user/override)
void initState() {
  super.initState();
  _pagingController.addPageRequestListener((pageKey) {
    _pagingController.value = PagingState(
      itemList: [],
      nextPageKey: pageKey,
    );
    _pagingController.refresh();
  });
  _pagingController.addPagingSource(MyPagingSource());
}

2.4 使用 PagedListViewPagedGridView

PagedListViewPagedGridViewpaging 插件提供的用于显示分页数据的组件。

[@override](/user/override)
Widget build(BuildContext context) {
  return Scaffold(
    appBar: AppBar(
      title: Text('Paging Example'),
    ),
    body: PagedListView<int, MyDataModel>(
      pagingController: _pagingController,
      builderDelegate: PagedChildBuilderDelegate<MyDataModel>(
        itemBuilder: (context, item, index) {
          return ListTile(
            title: Text('Item ${item.id}'),
          );
        },
      ),
    ),
  );
}
  • PagedListView 会自动处理分页加载,并在用户滚动到底部时触发加载更多数据。

3. 处理错误和加载状态

你可以在 builderDelegate 中处理错误和加载状态。

builderDelegate: PagedChildBuilderDelegate<MyDataModel>(
  itemBuilder: (context, item, index) {
    return ListTile(
      title: Text('Item ${item.id}'),
    );
  },
  firstPageProgressIndicatorBuilder: (context) {
    return Center(child: CircularProgressIndicator());
  },
  newPageProgressIndicatorBuilder: (context) {
    return Center(child: CircularProgressIndicator());
  },
  noItemsFoundIndicatorBuilder: (context) {
    return Center(child: Text('No items found'));
  },
  noMoreItemsIndicatorBuilder: (context) {
    return Center(child: Text('No more items'));
  },
  errorIndicatorBuilder: (context) {
    return Center(child: Text('Error loading items'));
  },
),

4. 刷新数据

你可以通过调用 _pagingController.refresh() 来刷新数据。

RefreshIndicator(
  onRefresh: () async {
    _pagingController.refresh();
  },
  child: PagedListView<int, MyDataModel>(
    pagingController: _pagingController,
    builderDelegate: PagedChildBuilderDelegate<MyDataModel>(
      itemBuilder: (context, item, index) {
        return ListTile(
          title: Text('Item ${item.id}'),
        );
      },
    ),
  ),
)

5. 清理资源

dispose 方法中清理 PagingController

[@override](/user/override)
void dispose() {
  _pagingController.dispose();
  super.dispose();
}
回到顶部