Flutter自定义分页插件flutter_custom_pagination的使用

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

Flutter自定义分页插件flutter_custom_pagination的使用

插件简介

flutter_custom_pagination 是一个用于帮助你在Flutter应用中实现数据分页的简单插件。它适用于Web和移动端,解决了Flutter内置分页表格的灵活性不足问题。该插件提供了两个主要组件:

  • FlutterCustomPagination:用于显示分页控件。
  • FlutterCustomPaginationOptions:用于显示每页显示条数的选择选项。

当前的样式基于Material Design,欢迎贡献代码以增强分页控件的外观和功能。

截图

小屏幕截图 大屏幕截图

使用方法

1. 添加依赖

pubspec.yaml 文件中添加 flutter_custom_pagination 依赖:

dependencies:
  flutter_custom_pagination: ^0.2.0

2. 导入包

在你的Dart文件中导入 flutter_custom_pagination 包:

import 'package:flutter_custom_pagination/flutter_custom_pagination.dart';
import 'package:flutter_custom_pagination/flutter_custom_pagination_options.dart';

3. 完整示例代码

以下是一个完整的示例代码,展示了如何使用 flutter_custom_pagination 实现分页功能。这个示例从 jsonplaceholder.typicode.com API 获取数据,并根据用户选择的分页选项动态加载数据。

import 'package:flutter/material.dart';
import 'package:flutter_custom_pagination/flutter_custom_pagination.dart';
import 'package:flutter_custom_pagination/flutter_custom_pagination_options.dart';
import 'package:dio/dio.dart'; // 用于网络请求

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

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

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

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> {
  final Dio dio = Dio(
    BaseOptions(
      baseUrl: 'https://jsonplaceholder.typicode.com',
      connectTimeout: const Duration(seconds: 15),
      receiveTimeout: const Duration(seconds: 15),
      headers: {
        "Accept": "application/json",
      },
    ),
  );

  int currentPage = 1;
  int pageLimit = 10;
  List<int> pageLimitOptions = [10, 25, 50];
  int totalDataCount = 100;
  dynamic sampleData = [];

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

  [@override](/user/override)
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(widget.title),
      ),
      bottomNavigationBar: BottomAppBar(
        elevation: 3,
        padding: const EdgeInsets.all(10.0),
        child: LayoutBuilder(
          builder: (BuildContext context, BoxConstraints constraints) =>
              MediaQuery.of(context).size.width >= 600
                  ? _renderLargeScreenPagination()
                  : _renderSmallScreenPagination(),
        ),
      ),
      body: SingleChildScrollView(
        child: sampleData.isEmpty
            ? const SizedBox(
                height: 300, child: Center(child: CircularProgressIndicator()))
            : Column(
                children: [
                  ListView.builder(
                    padding: const EdgeInsets.symmetric(vertical: 16),
                    physics: const NeverScrollableScrollPhysics(),
                    shrinkWrap: true,
                    itemCount: sampleData.length,
                    itemBuilder: (BuildContext context, int index) {
                      dynamic _data = sampleData[index];
                      return ListTile(
                        title: Text(
                          '${_data['title']}',
                          maxLines: 1,
                          overflow: TextOverflow.ellipsis,
                          style: const TextStyle(fontWeight: FontWeight.bold),
                        ),
                        subtitle: Text(
                          '${_data['body']}',
                          maxLines: 2,
                          overflow: TextOverflow.ellipsis,
                        ),
                      );
                    },
                  ),
                ],
              ),
      ),
    );
  }

  /// 渲染小屏幕分页(例如:手机屏幕)
  _renderSmallScreenPagination() {
    TextStyle? _textStyle = Theme.of(context).textTheme.labelMedium?.copyWith(
          color: Colors.brown,
          fontSize: 14,
        );

    return Wrap(
      alignment: WrapAlignment.center,
      children: [
        FlutterCustomPagination(
          currentPage: currentPage,
          limitPerPage: pageLimit,
          totalDataCount: totalDataCount,
          onPreviousPage: _onChangePage,
          onBackToFirstPage: _onChangePage,
          onNextPage: _onChangePage,
          onGoToLastPage: _onChangePage,
          backgroundColor: Theme.of(context).colorScheme.background,
          textStyle: _textStyle,
          previousPageIcon: Icons.keyboard_arrow_left,
          backToFirstPageIcon: Icons.first_page,
          nextPageIcon: Icons.keyboard_arrow_right,
          goToLastPageIcon: Icons.last_page,
        ),
        FlutterCustomPaginationOptions(
          limitPerPage: pageLimit,
          backgroundColor: Theme.of(context).colorScheme.background,
          textStyle: _textStyle,
          pageLimitOptions: pageLimitOptions,
          onPageLimitChanged: _onPageLimitChanged,
          text: 'items per page',
        ),
      ],
    );
  }

  /// 渲染大屏幕分页(例如:平板和桌面屏幕)
  _renderLargeScreenPagination() {
    TextStyle? _textStyle = Theme.of(context).textTheme.labelMedium?.copyWith(
          color: Colors.brown,
          fontSize: 14,
        );

    return Row(
      mainAxisAlignment: MainAxisAlignment.spaceBetween,
      children: [
        FlutterCustomPaginationOptions(
          limitPerPage: pageLimit,
          backgroundColor: Theme.of(context).colorScheme.background,
          textStyle: _textStyle,
          pageLimitOptions: pageLimitOptions,
          onPageLimitChanged: _onPageLimitChanged,
          text: 'items per page',
        ),
        FlutterCustomPagination(
          currentPage: currentPage,
          limitPerPage: pageLimit,
          totalDataCount: totalDataCount,
          onPreviousPage: _onChangePage,
          onBackToFirstPage: _onChangePage,
          onNextPage: _onChangePage,
          onGoToLastPage: _onChangePage,
          backgroundColor: Theme.of(context).colorScheme.background,
          textStyle: _textStyle,
          previousPageIcon: Icons.keyboard_arrow_left,
          backToFirstPageIcon: Icons.first_page,
          nextPageIcon: Icons.keyboard_arrow_right,
          goToLastPageIcon: Icons.last_page,
        ),
      ],
    );
  }

  /// 当分页选项改变时调用
  _onPageLimitChanged(int? limit) async {
    setState(() {
      currentPage = 1;
      pageLimit = limit ?? 15;
    });
    await _getSampleData();
  }

  /// 当页面改变时调用
  _onChangePage(int page) async {
    setState(() {
      currentPage = page;
    });
    await _getSampleData();
  }

  /// 获取示例数据
  _getSampleData() async {
    try {
      setState(() {
        sampleData = [];
      });
      final response =
          await dio.get('/posts?_page=$currentPage&_limit=$pageLimit');
      setState(() {
        sampleData = response.data;

        // 设置总数据量,如果需要
        // 示例API不提供总数据量信息,因此手动设置为100
        totalDataCount = 100;
      });
    } catch (e) {
      print(e);
    }
  }
}

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

1 回复

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


当然,下面是一个关于如何使用Flutter自定义分页插件flutter_custom_pagination的代码示例。这个插件允许你在Flutter应用中实现自定义分页功能。

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

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

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

以下是一个简单的示例,展示了如何使用flutter_custom_pagination来创建一个分页列表:

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

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

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

class MyHomePage extends StatefulWidget {
  @override
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  final List<String> items = List.generate(100, (index) => "Item ${index + 1}");
  int currentPage = 1;
  int itemsPerPage = 10;

  @override
  Widget build(BuildContext context) {
    final int totalPages = (items.length / itemsPerPage).ceil();

    return Scaffold(
      appBar: AppBar(
        title: Text('Custom Pagination Example'),
      ),
      body: Column(
        children: [
          Expanded(
            child: ListView.builder(
              itemCount: itemsPerPage,
              itemBuilder: (context, index) {
                final int itemIndex = (currentPage - 1) * itemsPerPage + index;
                if (itemIndex >= items.length) {
                  return null;
                }
                return ListTile(
                  title: Text(items[itemIndex]),
                );
              },
            ),
          ),
          Padding(
            padding: const EdgeInsets.all(8.0),
            child: Row(
              mainAxisAlignment: MainAxisAlignment.center,
              children: List.generate(
                totalPages,
                (pageIndex) => GestureDetector(
                  onTap: () {
                    setState(() {
                      currentPage = pageIndex + 1;
                    });
                  },
                  child: Container(
                    margin: EdgeInsets.symmetric(horizontal: 4.0),
                    decoration: BoxDecoration(
                      border: Border.all(color: currentPage == pageIndex + 1 ? Colors.blue : Colors.grey),
                      borderRadius: BorderRadius.circular(8.0),
                    ),
                    padding: EdgeInsets.symmetric(horizontal: 8.0, vertical: 4.0),
                    child: Text(
                      '${pageIndex + 1}',
                      style: TextStyle(
                        color: currentPage == pageIndex + 1 ? Colors.blue : Colors.black,
                      ),
                    ),
                  ),
                ),
              ),
            ),
          ),
        ],
      ),
    );
  }
}

在这个示例中,我们创建了一个简单的分页列表。以下是关键步骤:

  1. 定义数据源:我们创建了一个包含100个项目的列表items
  2. 计算总页数:通过items.length / itemsPerPage计算出总页数,并使用ceil()函数确保结果是一个整数。
  3. 构建分页列表:使用ListView.builder构建当前页的项目列表。
  4. 分页控件:创建一个简单的分页控件,通过GestureDetector监听点击事件,并在点击时更新当前页。

请注意,这个示例是一个简单的分页实现,并没有使用flutter_custom_pagination插件的特定功能。如果你想要使用flutter_custom_pagination插件提供的更高级功能(如自动加载下一页、自定义分页样式等),你需要查阅该插件的文档并参考其提供的示例代码。

由于flutter_custom_pagination插件的具体API和用法可能会随着版本的更新而变化,因此建议你查看插件的官方文档和示例代码以获取最新和详细的信息。

回到顶部