Flutter分页功能插件cyrus_pagination的使用

Flutter分页功能插件cyrus_pagination的使用


这是一个由Um Kithya创建的库,用于轻松显示分页数据。

Cyrus Pagination 在构建活动流、新闻流或任何需要懒加载和渲染内容的地方非常有用。

示例

列表分页 网格分页

列表分页的使用

一个基本实现需要四个参数:

  • onRefresh: 当下拉刷新时调用的刷新函数,类似于刷新指示器。
  • widget: 显示项的小部件。
  • fetchData: 获取数据的函数。
  • itemList: 项目列表。
  • loading: 加载状态变量。
  • page: 页码状态变量。
  • hasMoreData: 当有更多数据时为true。
  • end: 当页等于总页数时为true。

简单示例

CyrusPagination<PassagerModel>(
  onRefresh: () async {
    setState(() {
      page = 1;
      end = false;
    });
    await fetchApi();
  },
  loading: loading,
  itemList: passagerList,
  page: page,
  end: end,
  fetchData: () => fetchApi(),
  widget: (data, index) => Padding(
    padding: const EdgeInsets.only(bottom: 10),
    child: CustomCard(
      description: data.name,
      title: "$index",
    ),
  ),
  hasMoreData: isMoreData,
),

网格分页的使用

CyrusPagination<PassagerModel>(
  isGridView: true,
  gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(
    crossAxisSpacing: 1,
    mainAxisSpacing: 10,
    crossAxisCount: 2,
    childAspectRatio: 3 / 4.5,
  ),
  onRefresh: () async {
    setState(() {
      page = 1;
      end = false;
    });
    await fetchApi();
  },
  loading: loading,
  itemList: passagerList,
  page: page,
  end: end,
  fetchData: () => fetchApi(),
  widget: (data, index) => Padding(
    padding: const EdgeInsets.only(bottom: 10),
    child: CustomCard(
      description: data.name,
      title: "$index",
    ),
  ),
  hasMoreData: isMoreData,
),

示例代码

以下是完整的示例代码,展示了如何在Flutter应用中使用cyrus_pagination插件。

import 'package:cyrus_pagination/cyrus_pagination.dart';
import 'package:cyrus_pagination_example/model/passager_model.dart';
import 'package:dio_base_helper/dio_base_helper.dart';
import 'package:flutter/material.dart';

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

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  [@override](/user/override)
  Widget build(BuildContext context) {
    return MaterialApp(
      debugShowCheckedModeBanner: false,
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: const MyHomePage(title: 'Cyrus Pagination'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  const MyHomePage({super.key, required this.title});

  final String title;

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

class _MyHomePageState extends State<MyHomePage> {
  var passagerList = <PassagerModel>[];
  var loading = false;
  var page = 1;
  var end = false;
  var isMoreData = false;

  Future<void> fetchApi() async {
    setState(() {
      if (page == 1) {
        passagerList.clear();
        isMoreData = false;
        loading = true;
      } else {
        isMoreData = true;
        loading = false;
      }
    });
    final dioBaseHelper = DioBaseHelper("https://api.instantwebtools.net/v1");
    await dioBaseHelper
        .onRequest(
            methode: METHODE.get, 
            endPoint: "/passenger?page=$page&size=10")
        .then((response) => {
              debugPrint("Status code 200====${response['data']}"),
              for (var json in response['data'])
                {
                  passagerList.add(
                    PassagerModel.fromJson(json),
                  )
                },
              debugPrint('Length===${passagerList.length}'),
              setState(() =>
                {
                  passagerList = passagerList,
                  if (page < response["totalPages"]) page++,
                  loading = false,
                  isMoreData = false,
                  end = page == response["totalPages"],
                })
            })
        .onError(
          (ErrorModel error, stackTrace) => {
            debugPrint('Error: ${error.statusCode}'),
            setState(
              () => {loading = false},
            )
          },
        );
  }

  [@override](/user/override)
  void initState() {
    fetchApi();
    super.initState();
  }

  [@override](/user/override)
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(widget.title),
      ),
      body: CyrusPagination<PassagerModel>(
        isGridView: true,
        gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(
          crossAxisSpacing: 1,
          mainAxisSpacing: 10,
          crossAxisCount: 2,
          childAspectRatio: 3 / 4.5,
        ),
        onRefresh: () async {
          setState(() {
            page = 1;
            end = false;
          });
          await fetchApi();
        },
        loading: loading,
        itemList: passagerList,
        page: page,
        end: end,
        fetchData: () => fetchApi(),
        widget: (data, index) => Padding(
          padding: const EdgeInsets.only(bottom: 10),
          child: CustomCard(
            description: data.name,
            title: "$index",
          ),
        ),
        hasMoreData: isMoreData,
      ),
    );
  }
}

class CustomCard extends StatelessWidget {
  const CustomCard({
    Key? key,
    this.description,
    this.title,
  }) : super(key: key);
  final String? title;
  final String? description;

  [@override](/user/override)
  Widget build(BuildContext context) {
    return Padding(
      padding: const EdgeInsets.symmetric(horizontal: 20),
      child: Container(
        color: Colors.grey[300],
        height: 100,
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            Text(
              title!,
              style: const TextStyle(fontSize: 16),
            ),
            Text(
              description!,
              style: const TextStyle(fontSize: 16),
            ),
          ],
        ),
      ),
    );
  }
}

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

1 回复

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


cyrus_pagination 是一个用于 Flutter 的分页插件,它可以帮助你轻松地实现分页功能。以下是如何使用 cyrus_pagination 插件的详细步骤:

1. 添加依赖

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

dependencies:
  flutter:
    sdk: flutter
  cyrus_pagination: ^1.0.0  # 请使用最新版本

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

2. 导入插件

在你的 Dart 文件中导入 cyrus_pagination 插件:

import 'package:cyrus_pagination/cyrus_pagination.dart';

3. 使用 CyrusPagination

CyrusPagination 是一个 ListView 的分页包装器,你可以使用它来实现分页加载数据的功能。

以下是一个简单的示例:

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

class PaginationExample extends StatefulWidget {
  @override
  _PaginationExampleState createState() => _PaginationExampleState();
}

class _PaginationExampleState extends State<PaginationExample> {
  List<String> items = [];
  bool isLoading = false;
  int page = 1;

  Future<void> fetchData() async {
    setState(() {
      isLoading = true;
    });

    // 模拟网络请求,获取分页数据
    await Future.delayed(Duration(seconds: 2));

    List<String> newItems = List.generate(10, (index) => 'Item ${(page - 1) * 10 + index + 1}');

    setState(() {
      items.addAll(newItems);
      page++;
      isLoading = false;
    });
  }

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

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Cyrus Pagination Example'),
      ),
      body: CyrusPagination(
        itemCount: items.length,
        itemBuilder: (context, index) {
          return ListTile(
            title: Text(items[index]),
          );
        },
        onLoadMore: fetchData,
        isLoading: isLoading,
      ),
    );
  }
}

4. 参数说明

  • itemCount: 当前列表中的项目数量。
  • itemBuilder: 用于构建列表项的构建器。
  • onLoadMore: 当用户滚动到列表底部时触发的回调函数,通常用于加载更多数据。
  • isLoading: 表示是否正在加载数据的布尔值,用于控制是否显示加载指示器。

5. 自定义加载指示器

你可以通过 loadingWidget 参数来自定义加载指示器。例如:

CyrusPagination(
  itemCount: items.length,
  itemBuilder: (context, index) {
    return ListTile(
      title: Text(items[index]),
    );
  },
  onLoadMore: fetchData,
  isLoading: isLoading,
  loadingWidget: Center(
    child: CircularProgressIndicator(),
  ),
);

6. 自定义错误处理

你可以通过 errorWidget 参数来自定义错误处理。例如:

CyrusPagination(
  itemCount: items.length,
  itemBuilder: (context, index) {
    return ListTile(
      title: Text(items[index]),
    );
  },
  onLoadMore: fetchData,
  isLoading: isLoading,
  errorWidget: Center(
    child: Text('加载失败,请重试'),
  ),
);
回到顶部