Flutter自定义加载更多插件custom_loadmore的使用

Flutter自定义加载更多插件custom_loadmore的使用

简介

custom_loadmore 组件是一个方便的 Flutter 小部件,使得实现加载更多功能变得更加简单。它提供了一个灵活且易于使用的界面,并可以集成到任何 Flutter 项目中。这使开发者能够更专注于其他方面的开发,同时提供了控制布局和外观的能力。

特性

  • 加载更多功能
  • 可修改的布局
  • 内置UI功能处理

安装

要将此组件添加到你的项目中,请遵循以下步骤:

  1. 在你的 pubspec.yaml 文件中添加以下依赖:

    dependencies:
      custom_loadmore: ^1.0.0
    
  2. 运行 flutter pub get

  3. 使用该包时,确保导入该文件:

    import 'package:custom_loadmore/custom_loadmore.dart';
    

使用方法

步骤1:创建数据提供器

实现 ICustomLoadMoreDataProvider 接口。

class LoadmoreDataProvider implements ICustomLoadMoreDataProvider<int> {
  int indexStart = 0;
  int numberItemPerPage = 20;
  final int itemTotalCount = 100;
  bool haveMore = true;

  [@override](/user/override)
  Future<List<int>?> loadMore(int pageIndex, int pageSize) async {
    await Future.delayed(const Duration(seconds: 3)); // 模拟网络延迟
    if (!haveMore) {
      return [];
    }
    if (Random().nextBool()) {
      throw Exception("Load more failed"); // 模拟加载失败
    }
    var values = List.generate(numberItemPerPage, (index) => index + indexStart);
    indexStart += numberItemPerPage;

    if (indexStart >= itemTotalCount) {
      haveMore = false;
    }
    return values;
  }
}

步骤2:在 CustomLoadMore 小部件中提供数据提供器

class MyHomePage extends StatefulWidget {
  const MyHomePage({Key? key, required this.title}) : super(key: key);
  final String title;

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

class MyHomePageState extends State<MyHomePage> {
  final CustomLoadMoreController<int> customLoadMoreController =
      CustomLoadMoreController()
    ..addListener(() {
      print("Load more status: ${customLoadMoreController.currentItems}");
    });

  [@override](/user/override)
  Widget build(BuildContext context) {
    return SafeArea(
      child: Scaffold(
        extendBodyBehindAppBar: false,
        extendBody: true,
        body: Column(
          children: [
            const SizedBox(
              height: 24,
            ),
            Expanded(
              child: InfiniteLoadMoreList<int>(
                customLoadMoreController: customLoadMoreController,
                initBuilder: (context) {
                  return const Text("Init");
                },
                initLoaderBuilder: (context) {
                  return const CircularProgressIndicator();
                },
                initFailedBuilder: (context, error) {
                  return Text(" $error");
                },
                initSuccessWithNoDataBuilder: (context) {
                  return const Text("Init success with no data");
                },
                listItemBuilder: (context, index, items) {
                  return Container(
                    color: Colors.primaries[index % Colors.primaries.length],
                    width: 200,
                    child: Center(
                      child: Column(
                        children: [
                          // Text("$item...."),
                          Lottie.asset('assets/images/test2.json'),
                        ],
                      ),
                    ),
                  );
                },
                loadMoreBuilder: (context) {
                  return const ListTile(
                    title: Center(
                      child: CircularProgressIndicator(),
                    ),
                  );
                },
                loadMoreFailedBuilder: (context, error) {
                  return ListTile(
                    leading: const Text("Load more failed"),
                    trailing: ElevatedButton(
                      onPressed: () {
                        customLoadMoreController.retryLoadMore();
                      },
                      child: const Text("Reload"),
                    ),
                  );
                },
                noMoreBuilder: (context) {
                  return const Text("No more");
                },
                loadMoreDataProvider: LoadmoreDataProvider(),
              ),
            ),
            const Divider(
              height: 1,
              thickness: 1,
              color: Colors.black,
            ),
            Row(
              mainAxisAlignment: MainAxisAlignment.spaceEvenly,
              crossAxisAlignment: CrossAxisAlignment.center,
              children: [
                ElevatedButton(
                  onPressed: () {
                    customLoadMoreController.refresh();
                  },
                  child: const Text("Reload"),
                ),
                ElevatedButton(
                  onPressed: () {
                    print("current items: ${customLoadMoreController.currentItems}");
                  },
                  child: const Text("Log current items"),
                ),
              ],
            ),
            const SizedBox(
              height: 24,
            ),
          ],
        ),
      ),
    );
  }

  [@override](/user/override)
  void initState() {
    super.initState();
    print("current items: ${customLoadMoreController.currentItems}");
  }
}

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

1 回复

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


当然,下面是一个关于如何在Flutter中使用自定义加载更多插件custom_loadmore的示例代码。这个示例展示了如何集成并使用custom_loadmore插件来实现列表的加载更多功能。

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

dependencies:
  flutter:
    sdk: flutter
  custom_loadmore: ^x.y.z  # 请替换为实际的版本号

然后运行flutter pub get来获取依赖。

接下来,在你的Dart文件中(例如main.dart),你可以按照以下方式使用custom_loadmore

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

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

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

class LoadMoreExample extends StatefulWidget {
  @override
  _LoadMoreExampleState createState() => _LoadMoreExampleState();
}

class _LoadMoreExampleState extends State<LoadMoreExample> {
  List<String> items = List.generate(20, (i) => "Item ${i + 1}");
  bool isLoading = false;
  bool hasMore = true;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Load More Example'),
      ),
      body: CustomLoadMore(
        onLoadMore: _loadMore,
        isLoading: isLoading,
        hasMore: hasMore,
        builder: (context, state) {
          return ListView.builder(
            itemCount: items.length,
            itemBuilder: (context, index) {
              return ListTile(
                title: Text(items[index]),
              );
            },
          );
        },
        errorWidget: (context, refresh) {
          return Center(
            child: Column(
              mainAxisAlignment: MainAxisAlignment.center,
              children: <Widget>[
                Text('Load failed!'),
                SizedBox(height: 20),
                ElevatedButton(
                  onPressed: () {
                    setState(() {
                      isLoading = false;
                      // Reset state and try to load again
                      _loadMore(resetState: true);
                    });
                    refresh();
                  },
                  child: Text('Retry'),
                ),
              ],
            ),
          );
        },
        emptyWidget: Center(
          child: Text('No more data!'),
        ),
      ),
    );
  }

  Future<void> _loadMore({bool resetState = false}) async {
    if (resetState) {
      setState(() {
        items.clear();
        isLoading = true;
        hasMore = true;
      });
    } else if (hasMore) {
      setState(() => isLoading = true);
      
      // Simulate a network request with a delay
      await Future.delayed(Duration(seconds: 2));

      int nextStartIndex = items.length;
      int nextItemCount = 10;
      List<String> newItems = List.generate(nextItemCount, (i) => "Item ${nextStartIndex + i + 1}");

      // Update the state with new items
      setState(() {
        items.addAll(newItems);
        hasMore = items.length < 50;  // Example condition to stop loading
        isLoading = false;
      });
    }
  }
}

代码说明

  1. 依赖添加:在pubspec.yaml中添加custom_loadmore依赖。
  2. 主应用MyApp是一个简单的Flutter应用,它包含了一个主页面LoadMoreExample
  3. 状态管理_LoadMoreExampleState管理加载更多的状态,包括数据列表items、加载状态isLoading和是否有更多数据hasMore
  4. CustomLoadMore:使用CustomLoadMore组件,传入加载更多的回调函数onLoadMore、加载状态isLoading、是否有更多数据hasMore以及列表构建器builder
  5. 加载更多逻辑_loadMore函数模拟了一个网络请求,在请求完成后更新数据列表的状态。
  6. 错误处理和空状态:提供了errorWidgetemptyWidget来处理加载失败和没有更多数据的情况。

这个示例代码展示了如何使用custom_loadmore插件来实现一个简单的加载更多功能。你可以根据实际需求对代码进行修改和扩展。

回到顶部