Flutter无限分页加载插件easy_infinite_pagination的使用

发布于 1周前 作者 caililin 来自 Flutter

Flutter无限分页加载插件easy_infinite_pagination的使用

简介

easy_infinite_pagination 是一个简单且可定制的无限分页加载插件,适用于Flutter应用程序。它使得在应用中添加无限分页变得非常容易。只需几行代码,你就可以创建美观高效的分页列表、网格和页面视图。

Easy Infinite Pagination Demo

主要特性

  • 易于使用:无需额外控制器,类似于标准的Flutter widget。
  • 高度可定制:可以自定义分页指示器的外观。
  • 支持多种布局:包括ListView、GridView和PageView。
  • 兼容任何状态管理:如Bloc、Riverpod、Provider等。
  • 高效:优化处理大数据集。
  • 可扩展:支持自定义分页场景。

快速开始

添加依赖

首先,在你的pubspec.yaml文件中添加easy_infinite_pagination包:

dependencies:
  easy_infinite_pagination: ^latest_version

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

导入包

在Dart文件中导入该包:

import 'package:easy_infinite_pagination/easy_infinite_pagination.dart';

使用示例

基本用法

下面是一个简单的例子,展示如何使用InfiniteListView进行无限分页加载:

class SimpleExample extends StatefulWidget {
  const SimpleExample({super.key});

  @override
  State<SimpleExample> createState() => _SimpleExampleState();
}

class _SimpleExampleState extends State<SimpleExample> {
  List<String> _items = [];
  bool _isLoading = true;

  void _fetchData() async {
    setState(() {
      _isLoading = true;
    });
    await Future.delayed(const Duration(seconds: 3));
    setState(() {
      _isLoading = false;
      // 模拟网络请求或数据库查询,增加20个新项目到列表中
      _items = List.generate(_items.length + 20, (i) => 'Item ${i + 1}');
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('Simple Example'),
        backgroundColor: Theme.of(context).colorScheme.inversePrimary,
      ),
      body: InfiniteListView(
        delegate: PaginationDelegate(
          itemCount: _items.length,
          itemBuilder: (_, index) => ListTile(
            title: Text(_items[index]),
          ),
          isLoading: _isLoading,
          onFetchData: _fetchData,
        ),
      ),
    );
  }
}

自定义分页指示器

你可以根据需要自定义不同的分页指示器:

InfiniteListView(
  delegate: PaginationDelegate(
    itemCount: _items.length,
    itemBuilder: (context, index) => ListTile(
      title: DefaultListTile(index: index),
    ),
    isLoading: _isLoading,
    onFetchData: _fetchData,
    firstPageLoadingBuilder: (context) => const FirstPageLoadingIndicator(),
    firstPageErrorBuilder: (context, onRetry) => FirstPageErrorIndicator(onRetry: onRetry),
    firstPageNoItemsBuilder: (context) => const FirstPageNoItemsFoundedIndicator(),
    loadMoreLoadingBuilder: (context) => const LoadMoreLoadingIndicator(),
    loadMoreErrorBuilder: (context, onRetry) => LoadMoreErrorIndicator(onRetry: onRetry),
    loadMoreNoMoreItemsBuilder: (context) => const LoadMoreNoMoreItemsIndicator(),
  ),
)

控制数据获取时机

通过设置invisibleItemsThresholdfetchDataOnStart参数,你可以控制何时开始加载更多数据:

InfiniteListView(
  delegate: PaginationDelegate(
    invisibleItemsThreshold: 5, // 当剩余不可见项为5时触发加载
    fetchDataOnStart: true,     // 启动时是否立即加载数据,默认为true
    ...
  ),
)

结合Bloc使用

如果你使用的是Bloc进行状态管理,可以像这样集成:

InfiniteListView.separated(
  delegate: PaginationDelegate(
    isLoading: state is PostsFetchLoading,
    hasError: state is PostsFetchError,
    hasReachedMax: context.read<PostsListCubit>().hasReachedMax,
    invisibleItemsThreshold: 5,
    itemCount: posts.length,
    itemBuilder: (context, index) {
      final post = posts[index];
      return PostWidget(post: post);
    },
    firstPageErrorBuilder: state is PostsFetchError
      ? (context, onRetry) => CustomErrorScreen(errorMessage: state.message, onRetry: onRetry)
      : null,
    onFetchData: () async {
      await context.read<PostsListCubit>().fetchPosts();
    },
  ),
  separatorBuilder: (context, index) => const Divider(),
)

Sliver布局支持

对于更复杂的布局,比如SliverGrid,也可以轻松实现无限分页:

SliverPadding(
  padding: const EdgeInsets.all(16.0),
  sliver: SliverInfiniteGridView(
    gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(
      crossAxisCount: 2,
      crossAxisSpacing: 10.0,
      mainAxisSpacing: 10.0,
    ),
    delegate: PaginationDelegate(
      isLoading: state.isLoading,
      hasError: state.hasError,
      hasReachedMax: state.hasReachedMax,
      invisibleItemsThreshold: 5,
      itemCount: state.posts.length,
      itemBuilder: (context, index) {
        final post = state.posts[index];
        return PostGridWidget(post: post);
      },
      onFetchData: () async {
        await context.read<PostsGridCubit>().fetchPosts();
      },
    ),
  ),
)

PageView支持

如果你想实现垂直滚动的分页效果,可以使用InfinitePageView

InfinitePageView(
  scrollDirection: Axis.vertical,
  delegate: PaginationDelegate(
    itemCount: _items.length,
    itemBuilder: (_, index) => ListTile(
      title: PageViewItem(index: index),
    ),
    isLoading: _isLoading,
    invisibleItemsThreshold: 1,
    onFetchData: _fetchData,
  ),
)

自定义分页布局

如果默认提供的布局不能满足需求,还可以通过PaginationLayoutBuilder来自定义分页逻辑:

return PaginationLayoutBuilder(
  layoutStrategy: LayoutStrategy.box,
  delegate: paginationDelegate,
  useShrinkWrapForFirstPageIndicators: _useShrinkWrapForFirstPageIndicators,
  layoutChildBuilder: (
    context,
    itemBuilder,
    itemCount,
    bottomLoaderBuilder,
  ) => MasonryGridView.custom(
    gridDelegate: gridDelegate,
    mainAxisSpacing: mainAxisSpacing,
    crossAxisSpacing: crossAxisSpacing,
    padding: padding,
    childrenDelegate: PaginationLayoutBuilder.createSliverChildDelegate(
      builder: itemBuilder,
      childCount: itemCount,
      bottomLoaderBuilder: bottomLoaderBuilder,
      addAutomaticKeepAlives: addAutomaticKeepAlives,
      addRepaintBoundaries: addRepaintBoundaries,
      addSemanticIndexes: addSemanticIndexes,
    ),
  ),
)

更多信息

  • GitHub仓库 - 提交问题或贡献代码。
  • 如果遇到问题,请在GitHub Issues中提交报告。
  • 需要帮助时,可以通过GitHub联系作者。

希望这个插件能帮助你在Flutter项目中轻松实现无限分页功能!


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

1 回复

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


当然,下面是一个关于如何在Flutter中使用easy_infinite_pagination插件实现无限分页加载的示例代码。这个插件可以帮助你轻松地在Flutter应用中实现分页加载功能。

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

dependencies:
  flutter:
    sdk: flutter
  easy_infinite_pagination: ^x.y.z  # 请替换为最新版本号

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

接下来,在你的Dart文件中,你可以按照以下步骤实现无限分页加载:

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

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Infinite Pagination Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: InfinitePaginationDemo(),
    );
  }
}

class InfinitePaginationDemo extends StatefulWidget {
  @override
  _InfinitePaginationDemoState createState() => _InfinitePaginationDemoState();
}

class _InfinitePaginationDemoState extends State<InfinitePaginationDemo> {
  final List<String> items = [];
  final PaginationController paginationController = PaginationController(firstPageKey: 0);

  @override
  void initState() {
    super.initState();
    loadMoreItems();
  }

  Future<void> loadMoreItems() async {
    // 模拟网络请求延迟
    await Future.delayed(Duration(seconds: 1));

    // 获取当前页码
    final int pageKey = paginationController.currentPageKey;

    // 模拟分页数据
    final List<String> newItems = List.generate(
      20, // 每页加载20个数据
      (index) => "Item ${(pageKey * 20) + index + 1}",
    );

    // 更新状态
    setState(() {
      items.addAll(newItems);
      // 如果数据已经加载完毕,可以调用finishLoading()来停止加载更多
      // paginationController.finishLoading();
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Infinite Pagination Demo'),
      ),
      body: EasyInfinitePagination(
        controller: paginationController,
        onLoadMore: loadMoreItems,
        itemBuilder: (context, index) {
          return ListTile(
            title: Text(items[index]),
          );
        },
        itemCount: items.length,
        errorWidget: Center(child: Text('加载失败,请稍后再试')),
        emptyWidget: Center(child: Text('暂无数据')),
      ),
    );
  }
}

代码解释:

  1. 依赖添加:在pubspec.yaml中添加easy_infinite_pagination依赖。
  2. PaginationController:创建一个PaginationController实例来管理分页状态。
  3. loadMoreItems方法:模拟一个网络请求,加载更多的数据。在实际应用中,你应该在这里调用你的API来获取数据。
  4. EasyInfinitePagination:使用EasyInfinitePagination组件来显示分页数据。
    • controller:传入PaginationController实例。
    • onLoadMore:当需要加载更多数据时调用的方法。
    • itemBuilder:构建每个列表项的Widget。
    • itemCount:当前加载的数据项总数。
    • errorWidget:加载出错时显示的Widget。
    • emptyWidget:数据为空时显示的Widget。

这样,你就成功地在Flutter应用中实现了无限分页加载功能。记得根据实际需求调整代码,比如替换网络请求部分。

回到顶部