Flutter分页加载插件load_more_pagination的使用

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

Flutter分页加载插件 load_more_pagination 的使用

load_more_pagination 是一个高度可定制的Flutter插件,支持懒加载和显示小块数据,当用户滚动到屏幕底部时自动加载更多内容。它支持多种类型的列表视图构建器,并提供了平滑的动画效果,适用于Android、iOS、WebApp和DesktopApp。

主要特性

  • 支持任何类型的列表视图构建器。
  • 支持无尽滚动、懒加载、渐进加载等分页方式。
  • 提供了非常流畅的动画效果。

安装

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

dependencies:
  load_more_pagination: ^latest_version

或者直接运行以下命令来添加依赖:

flutter pub add load_more_pagination

然后在你的 Dart 文件中导入该包:

import 'package:load_more_pagination/load_more_pagination.dart';

使用示例

基本用法

下面是一个简单的例子,展示了如何使用 LoadMorePagination 组件进行分页加载:

import 'dart:async';
import 'package:flutter/material.dart';
import 'package:load_more_pagination/load_more_pagination.dart';

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

class MyApp extends StatelessWidget {
  const MyApp({Key? key}) : super(key: key);

  [@override](/user/override)
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Pagination Demo',
      theme: ThemeData(
        primarySwatch: Colors.red,
        platform: TargetPlatform.iOS,
      ),
      home: const MyHomePage(),
    );
  }
}

class MyHomePage extends StatefulWidget {
  const MyHomePage({Key? key}) : super(key: key);

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

class _MyHomePageState extends State<MyHomePage> {
  List<int> productList = [];
  bool isFinishLoadMore = false;

  [@override](/user/override)
  void initState() {
    super.initState();
    initiateList(); // 初始化列表数据
  }

  void initiateList() {
    productList.addAll(List.generate(10, (v) => v));
    setState(() {});
  }

  Future<bool> _loadMoreData() async {
    await Future.delayed(const Duration(seconds: 2));
    if (!isFinishLoadMore) {
      initiateList();
    }
    if (productList.length >= 30) {
      isFinishLoadMore = true;
    }
    return true;
  }

  Future<void> _refresh() async {
    await Future.delayed(const Duration(seconds: 2));
    productList.clear();
    isFinishLoadMore = false;
    initiateList();
  }

  [@override](/user/override)
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text("Load More List"),
      ),
      body: RefreshIndicator(
        onRefresh: _refresh,
        child: LoadMorePagination(
          isFinish: isFinishLoadMore,
          onLoadMorePagination: _loadMoreData,
          loaderColor: Colors.green,
          whenEmptyLoad: true,
          delegate: const DefaultLoadMorePaginationDelegate(),
          textBuilder: DefaultLoadMorePaginationTextBuilder.english,
          child: ListView.builder(
            itemBuilder: (BuildContext context, int index) {
              return ListTile(
                title: Text('Product ${index + 1}'),
                subtitle: const Text('Subtitle'),
              );
            },
            itemCount: productList.length,
          ),
        ),
      ),
    );
  }
}

使用 GetX 状态管理

如果你使用的是 GetX 状态管理库,可以参考以下示例代码:

import 'package:get/get.dart';
import 'package:flutter/material.dart';
import 'package:load_more_pagination/load_more_pagination.dart';

class OrdersNotificationController extends GetxController {
  final Repository repository = Repository();
  RxList<OrderListModel> myOrdersList = <OrderListModel>[].obs;
  RxBool isFinishLoadMore = false.obs;
  RxBool isOrdersListLoading = true.obs;
  RxInt pageNumber = 1.obs;

  Future<bool> loadMore() async {
    await Future.delayed(const Duration(milliseconds: 2000));
    await getOrdersList(shouldShowLoader: false);
    return true;
  }

  Future<void> getOrdersList({bool shouldShowLoader = true, bool isPageRefresh = false}) async {
    try {
      String qParams = "pageSize=20&current=${pageNumber.value}";
      if (shouldShowLoader) isOrdersListLoading(true);
      List<dynamic>? response = await repository.getApiCall(url: "order/list?$qParams");
      if (isPageRefresh) myOrdersList.clear();
      if (response != null && response.isNotEmpty) {
        for (var element in response) {
          myOrdersList.add(OrderListModel.fromJson(element));
        }
        pageNumber.value += 1;
      } else {
        isFinishLoadMore(true); // 当没有更多数据时设置为true
      }
      isOrdersListLoading(false);
    } catch (e, stackTrace) {
      isOrdersListLoading(false);
    }
  }
}

class MyOrdersScreen extends StatefulWidget {
  const MyOrdersScreen({Key? key}) : super(key: key);

  [@override](/user/override)
  State<MyOrdersScreen> createState() => _MyOrdersScreenState();
}

class _MyOrdersScreenState extends State<MyOrdersScreen> {
  final OrdersNotificationController _ordersNC = Get.find();

  [@override](/user/override)
  void initState() {
    WidgetsBinding.instance.addPostFrameCallback((_) => init());
    super.initState();
  }

  void init() {
    bool isLogin = CommonLogics.checkUserLogin();
    if (isLogin) {
      _ordersNC.isFinishLoadMore(false);
      _ordersNC.pageNumber(1);
      _ordersNC.getOrdersList(shouldShowLoader: false, isPageRefresh: true);
    }
  }

  [@override](/user/override)
  Widget build(BuildContext context) {
    return Scaffold(
      backgroundColor: CommonColors.appBgColor,
      body: Obx(() {
        return _ordersNC.isOrdersListLoading.value
            ? const Center(child: CircularProgressIndicator(color: CommonColors.appColor))
            : ScrollConfiguration(
                behavior: const ScrollBehavior().copyWith(overscroll: false),
                child: RefreshIndicator(
                  onRefresh: () async {
                    _ordersNC.isFinishLoadMore(false);
                    _ordersNC.pageNumber(1);
                    await _ordersNC.getOrdersList(shouldShowLoader: false, isPageRefresh: true);
                  },
                  child: _ordersNC.myOrdersList.isNotEmpty
                      ? LoadMore(
                          isFinish: _ordersNC.isFinishLoadMore.value,
                          onLoadMore: _ordersNC.loadMore,
                          textBuilder: DefaultLoadMoreTextBuilder.english,
                          child: ListView.builder(
                            shrinkWrap: true,
                            itemCount: _ordersNC.myOrdersList.length,
                            itemBuilder: (context, index) {
                              return GestureDetector(
                                onTap: () {
                                  Get.to(() => OrderDetailsScreen(orderId: _ordersNC.myOrdersList[index].orderItemId));
                                },
                                child: OrderTileWidget(orderListItem: _ordersNC.myOrdersList[index]),
                              );
                            },
                          ),
                        )
                      : const NoDataScreen(),
                ),
              );
      }),
    );
  }
}

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

1 回复

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


当然,以下是一个关于如何在Flutter中使用load_more_pagination插件进行分页加载的示例代码。这个插件能够帮助你实现列表数据的分页加载功能,非常适合用于展示大量数据的情况,比如新闻列表、社交媒体帖子等。

首先,确保你已经在pubspec.yaml文件中添加了load_more_pagination依赖:

dependencies:
  flutter:
    sdk: flutter
  load_more_pagination: ^0.3.0  # 请检查最新版本号

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

接下来,下面是一个完整的示例代码,展示了如何使用load_more_pagination插件:

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

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

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

class PaginationDemo extends StatefulWidget {
  @override
  _PaginationDemoState createState() => _PaginationDemoState();
}

class _PaginationDemoState extends State<PaginationDemo> {
  final PaginationController<int> _paginationController =
      PaginationController(initialPage: 1);

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

  Future<void> fetchData(int page) async {
    // 模拟网络请求,这里简单地使用延时来模拟
    await Future.delayed(Duration(seconds: 1));
    List<int> newItems = List.generate(
      10, // 每页加载10个项目
      (index) => (page - 1) * 10 + index + 1,
    );
    _paginationController.appendLastPageItems(newItems);
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Pagination Demo'),
      ),
      body: LoadMorePagination<int>(
        paginationController: _paginationController,
        builderDelegate: PaginationBuilderDelegate<int>(
          itemBuilder: (_, item, index) => ListTile(
            title: Text('Item $item'),
          ),
          errorWidget: Center(child: Text('Error occurred')),
          emptyListWidget: Center(child: Text('No data')),
          loadingWidget: Center(child: CircularProgressIndicator()),
        ),
        onLoadMore: fetchData,
      ),
    );
  }
}

代码解释

  1. 依赖引入:确保在pubspec.yaml中引入了load_more_pagination包。
  2. PaginationController:创建PaginationController实例,用于管理分页状态。
  3. fetchData方法:模拟一个网络请求,这里使用Future.delayed来模拟网络延迟。实际使用时,你应该替换成真实的网络请求。
  4. LoadMorePagination:使用LoadMorePagination组件来展示分页列表。
    • paginationController:绑定分页控制器。
    • builderDelegate:使用PaginationBuilderDelegate来定义列表项的构建方式,包括错误、空列表和加载中的情况。
    • onLoadMore:定义加载更多数据的方法。

这个示例展示了如何使用load_more_pagination插件来实现分页加载功能。你可以根据自己的需求调整fetchData方法中的逻辑,以适应真实的API请求和数据结构。

回到顶部