Flutter分页加载插件paginable的使用

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

Flutter分页加载插件paginable的使用

Flutter应用程序中,分页加载(pagination)是一种常见的需求,特别是在处理长列表或大数据集时。为了简化这一过程,paginable插件提供了一种简单且灵活的方式来实现分页加载功能。本文将详细介绍如何使用paginable插件,并提供完整的示例代码。

Paginable Widgets

paginable插件提供了几个用于分页加载的组件:

  • PaginableListView: 类似于标准的ListView.builderListView.separated,但支持分页加载。
  • PaginableCustomScrollView: 类似于CustomScrollView,但支持分页加载。
  • PaginableSliverChildBuilderDelegate: 用于CustomScrollView中的子项构建器,支持分页加载。

使用PaginableListView

使用PaginableListView.builder()

下面是一个使用PaginableListView.builder()的完整示例:

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

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

  @override
  Widget build(BuildContext context) {
    return SafeArea(
      child: Scaffold(
        appBar: AppBar(
          title: const Text('PaginableListView Example'),
        ),
        body: PaginableListView.builder(
          loadMore: () async {
            // 模拟加载更多数据
            await Future.delayed(Duration(seconds: 2));
            // 在这里可以添加实际的网络请求或其他数据获取逻辑
          },
          errorIndicatorWidget: (exception, tryAgain) => Container(
            color: Colors.redAccent,
            height: 130,
            child: Column(
              mainAxisAlignment: MainAxisAlignment.center,
              children: [
                Text(
                  exception.toString(),
                  style: const TextStyle(fontSize: 16),
                ),
                const SizedBox(height: 16.0),
                ElevatedButton(
                  style: ButtonStyle(
                    backgroundColor: MaterialStateProperty.all(Colors.green),
                  ),
                  onPressed: tryAgain,
                  child: const Text('Try Again'),
                ),
              ],
            ),
          ),
          progressIndicatorWidget: const SizedBox(
            height: 100,
            child: Center(
              child: CircularProgressIndicator(),
            ),
          ),
          itemBuilder: (context, index) => ListTile(
            leading: CircleAvatar(
              child: Text(index.toString()),
            ),
            title: Text('Item $index'),
          ),
          itemCount: 20,
        ),
      ),
    );
  }
}

使用PaginableListView.separated()

如果你需要在每个列表项之间添加分隔符,可以使用PaginableListView.separated()

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

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

  @override
  Widget build(BuildContext context) {
    return SafeArea(
      child: Scaffold(
        appBar: AppBar(
          title: const Text('PaginableListView Separated Example'),
        ),
        body: PaginableListView.separated(
          separatorBuilder: (context, index) => const Divider(thickness: 1.2),
          loadMore: () async {
            // 模拟加载更多数据
            await Future.delayed(Duration(seconds: 2));
            // 在这里可以添加实际的网络请求或其他数据获取逻辑
          },
          errorIndicatorWidget: (exception, tryAgain) => Container(
            color: Colors.redAccent,
            height: 130,
            child: Column(
              mainAxisAlignment: MainAxisAlignment.center,
              children: [
                Text(
                  exception.toString(),
                  style: const TextStyle(fontSize: 16),
                ),
                const SizedBox(height: 16.0),
                ElevatedButton(
                  style: ButtonStyle(
                    backgroundColor: MaterialStateProperty.all(Colors.green),
                  ),
                  onPressed: tryAgain,
                  child: const Text('Try Again'),
                ),
              ],
            ),
          ),
          progressIndicatorWidget: const SizedBox(
            height: 100,
            child: Center(
              child: CircularProgressIndicator(),
            ),
          ),
          itemBuilder: (context, index) => ListTile(
            leading: CircleAvatar(
              child: Text(index.toString()),
            ),
            title: Text('Item $index'),
          ),
          itemCount: 20,
        ),
      ),
    );
  }
}

使用PaginableCustomScrollView与PaginableSliverChildBuilderDelegate

使用build()方法

下面是使用PaginableCustomScrollViewPaginableSliverChildBuilderDelegate.build()的示例:

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

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

  @override
  Widget build(BuildContext context) {
    return SafeArea(
      child: Scaffold(
        appBar: AppBar(
          title: const Text('PaginableCustomScrollView Example'),
        ),
        body: PaginableCustomScrollView(
          loadMore: () async {
            // 模拟加载更多数据
            await Future.delayed(Duration(seconds: 2));
            // 在这里可以添加实际的网络请求或其他数据获取逻辑
          },
          slivers: [
            const SliverAppBar(
              floating: true,
              title: Text('PaginableCustomScrollView'),
            ),
            SliverList(
              delegate: PaginableSliverChildBuilderDelegate(
                (context, index) => ListTile(
                  leading: CircleAvatar(
                    child: Text(index.toString()),
                  ),
                  title: Text('Item $index'),
                ),
                errorIndicatorWidget: (exception, tryAgain) => Container(
                  color: Colors.redAccent,
                  height: 130,
                  child: Column(
                    mainAxisAlignment: MainAxisAlignment.center,
                    children: [
                      Text(
                        exception.toString(),
                        style: const TextStyle(fontSize: 16),
                      ),
                      const SizedBox(height: 16.0),
                      ElevatedButton(
                        style: ButtonStyle(
                          backgroundColor: MaterialStateProperty.all(Colors.green),
                        ),
                        onPressed: tryAgain,
                        child: const Text('Try Again'),
                      ),
                    ],
                  ),
                ),
                progressIndicatorWidget: const SizedBox(
                  height: 100,
                  child: Center(
                    child: CircularProgressIndicator(),
                  ),
                ),
                childCount: 20,
              ).build(),
            ),
          ],
        ),
      ),
    );
  }
}

使用separated()方法

如果你需要在每个列表项之间添加分隔符,可以使用PaginableSliverChildBuilderDelegate.separated()

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

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

  @override
  Widget build(BuildContext context) {
    return SafeArea(
      child: Scaffold(
        appBar: AppBar(
          title: const Text('PaginableCustomScrollView Separated Example'),
        ),
        body: PaginableCustomScrollView(
          loadMore: () async {
            // 模拟加载更多数据
            await Future.delayed(Duration(seconds: 2));
            // 在这里可以添加实际的网络请求或其他数据获取逻辑
          },
          slivers: [
            const SliverAppBar(
              floating: true,
              title: Text('PaginableCustomScrollView'),
            ),
            SliverList(
              delegate: PaginableSliverChildBuilderDelegate(
                (context, index) => ListTile(
                  leading: CircleAvatar(
                    child: Text(index.toString()),
                  ),
                  title: Text('Item $index'),
                ),
                errorIndicatorWidget: (exception, tryAgain) => Container(
                  color: Colors.redAccent,
                  height: 130,
                  child: Column(
                    mainAxisAlignment: MainAxisAlignment.center,
                    children: [
                      Text(
                        exception.toString(),
                        style: const TextStyle(fontSize: 16),
                      ),
                      const SizedBox(height: 16.0),
                      ElevatedButton(
                        style: ButtonStyle(
                          backgroundColor: MaterialStateProperty.all(Colors.green),
                        ),
                        onPressed: tryAgain,
                        child: const Text('Try Again'),
                      ),
                    ],
                  ),
                ),
                progressIndicatorWidget: const SizedBox(
                  height: 100,
                  child: Center(
                    child: CircularProgressIndicator(),
                  ),
                ),
                childCount: 20,
              ).separated(
                (context, index) => const Divider(thickness: 1.2),
              ),
            ),
          ],
        ),
      ),
    );
  }
}

注意事项

  • paginable插件仅负责在滚动接近底部时执行loadMore函数、显示错误指示器和进度指示器。它不管理状态,因此你需要根据自己的需求选择合适的状态管理方案。
  • 如果你在使用过程中遇到问题或有改进建议,欢迎通过GitHub提交issue或pull request。

希望这篇文章能帮助你更好地理解和使用paginable插件!如果有任何疑问,欢迎随时提问。


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

1 回复

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


当然,以下是一个关于如何在Flutter中使用paginable插件进行分页加载的示例代码。paginable是一个帮助实现分页加载数据的库。在这个例子中,我们将展示如何结合网络请求和分页加载来展示一个列表。

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

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

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

接下来是示例代码:

import 'package:flutter/material.dart';
import 'package:paginable/paginable.dart';
import 'package:http/http.dart' as http;

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

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

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

class _MyHomePageState extends State<MyHomePage> {
  final PaginableController<Map<String, dynamic>> _controller =
      PaginableController<Map<String, dynamic>>(
    pageKey: 'page',
    itemsPerPageKey: 'per_page',
    initialPage: 1,
    itemsPerPage: 20,
  );

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

  Future<void> loadData() async {
    try {
      final response = await http.get(
        Uri.parse('https://api.example.com/items'), // 替换为你的API URL
        headers: <String, String>{
          'Content-Type': 'application/json',
        },
      );

      if (response.statusCode == 200) {
        final data = jsonDecode(response.body) as Map<String, dynamic>;
        final items = data['data'] as List<Map<String, dynamic>>;
        _controller.addItems(items);
      } else {
        throw Exception('Failed to load data');
      }
    } catch (e) {
      _controller.setError(e.toString());
    }
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Flutter Paginable Demo'),
      ),
      body: RefreshIndicator(
        onRefresh: () async {
          _controller.reset();
          await loadData();
        },
        child: PaginableListView<Map<String, dynamic>>(
          controller: _controller,
          itemBuilder: (context, item, index) {
            return ListTile(
              title: Text(item['name'] as String), // 根据你的数据结构调整
            );
          },
          loadingBuilder: (context) {
            return Center(child: CircularProgressIndicator());
          },
          errorBuilder: (context, error) {
            return Center(child: Text('Error: $error'));
          },
          emptyBuilder: (context) {
            return Center(child: Text('No items found'));
          },
          onLoadMore: () async {
            await loadData();
          },
        ),
      ),
    );
  }
}

代码解释:

  1. PaginableController: 创建一个PaginableController实例,用于管理分页逻辑。pageKeyitemsPerPageKey用于指定API请求中的分页参数名,initialPageitemsPerPage设置初始分页参数。

  2. loadData: 这是一个异步函数,用于从API加载数据。这里使用http.get发送请求,解析响应数据,并使用_controller.addItems(items)将数据添加到分页控制器中。

  3. initState: 在组件初始化时调用loadData函数加载初始数据。

  4. PaginableListView: 使用PaginableListView来显示分页数据。itemBuilder用于构建列表项,loadingBuildererrorBuilderemptyBuilder分别用于显示加载中、错误和空列表时的界面。onLoadMore在需要加载更多数据时调用。

  5. RefreshIndicator: 用于实现下拉刷新功能,当用户下拉刷新时,调用_controller.reset()重置分页状态并重新加载数据。

这个示例展示了如何使用paginable插件在Flutter中实现分页加载,你可以根据自己的需求进一步调整和优化代码。

回到顶部