Flutter分页构建项插件paginated_items_builder的使用

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

Flutter分页构建项插件 paginated_items_builder 的使用

PaginatedItemsBuilder 是一个用于处理Flutter应用中分页数据展示的插件,支持内部或外部状态管理,内置了加载动画和错误处理等功能。以下是如何使用这个插件的详细指南。

添加依赖

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

dependencies:
  flutter:
    sdk: flutter

  paginated_items_builder:

使用示例

示例1:带有控制器的状态管理

假设你有一个博客文章列表的数据源,可以按照如下方式实现:

定义控制器和API函数

在控制器中定义一个变量来存储博客文章的响应,并提供一个公共getter以便在UI中访问。

class PostsController with ChangeNotifier {
  PaginatedItemsResponse<Post>? _postsResponse;

  PaginatedItemsResponse<Post>? get postsResponse => _postsResponse;

  Future<PaginatedItemsResponse<Post>?> updatePosts({bool reset = false}) async {
    final res = await apiFunction(
      startKey: reset ? null : _postsResponse?.paginationKey,
    );

    if (reset || _postsResponse == null) {
      _postsResponse = res;
    } else {
      _postsResponse?.update(res);
    }
    notifyListeners();
    return _postsResponse;
  }

  Future<PaginatedItemsResponse<Post>> apiFunction({dynamic startKey}) async {
    final res = await _api.getPosts(startKey: startKey);

    return PaginatedItemsResponse<Post>(
      listItems: res.data?.posts,
      paginationKey: res.data?.paginationKey,
      idGetter: (post) => post.id,
    );
  }
}

在Widget树中使用

class HomeScreen extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    final postsCon = Provider.of<PostsController>(context);

    return SafeArea(
      child: Scaffold(
        body: PaginatedItemsBuilder<Post>(
          response: postsCon.postsResponse,
          showLoaderOnResetGetter: (itemsFetchScope) => [
            ItemsFetchScope.noItemsRefresh,
            ItemsFetchScope.onErrorRefresh,
            ItemsFetchScope.pullDownToRefresh,
          ].contains(itemsFetchScope),
          fetchPageData: (reset) => postsCon.updatePosts(reset: reset),
          itemBuilder: (context, idx, post) => PostCard(post),
          loaderItemsCount: 12,
        ),
      ),
    );
  }
}

示例2:无控制器的状态管理

如果你不想使用控制器,可以直接在 PaginationItemsStateHandler 中处理状态:

Future<PaginatedItemsResponse<Post>> updatePosts(dynamic paginationKey) async {
  return await PostsRepository.getPosts(startKey: paginationKey);
}

@override
Widget build(BuildContext context) {
  return SafeArea(
    child: Scaffold(
      body: PaginationItemsStateHandler<Post>(
        fetchPageData: updatePosts,
        builder: (response, fetchPageData) {
          return PaginatedItemsBuilder<Post>(
            response: response,
            fetchPageData: fetchPageData,
            itemBuilder: (context, _, post) => PostCard(post),
            loaderItemsCount: 12,
          );
        },
      ),
    ),
  );
}

配置与自定义

你可以通过 PaginatedItemsBuilderConfig 来配置一些默认设置,例如模拟数据获取器、加载动画颜色等。

class MockItems {
  static dynamic getByType<T>([String? mockItemKey]) {
    final key = mockItemKey ?? T.toString();
    switch (key) {
      case 'Category':
        return _category;
    }
  }

  static final _category = Category.fromJson({
    'id': 'id',
    'name': '■■■■■■',
  });
}

MaterialApp(
  title: 'PaginatedItemsBuilder Demo',
  builder: (context, child) {
    late final Color shimmerBaseColor;
    late final Color shimmerHighlightColor;

    switch (Theme.of(context).brightness) {
      case Brightness.light:
        shimmerBaseColor = Colors.grey[300]!;
        shimmerHighlightColor = Colors.grey[100]!;
        break;
      case Brightness.dark:
        shimmerBaseColor = const Color(0xFF031956);
        shimmerHighlightColor = const Color(0x80031956);
        break;
    }

    PaginatedItemsBuilder.config = PaginatedItemsBuilderConfig(
      mockItemGetter: MockItems.getByType,
      shimmerConfig: ShimmerConfig(
        baseColor: shimmerBaseColor,
        highlightColor: shimmerHighlightColor,
        duration: const Duration(seconds: 1),
      ),
    );

    return child!;
  },
);

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

1 回复

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


当然,下面是一个关于如何在Flutter中使用paginated_items_builder插件进行分页构建的示例代码。这个插件可以帮助你以分页的方式加载和显示大量数据,而不需要一次性加载所有数据,从而提高性能和用户体验。

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

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

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

接下来是一个完整的示例代码,展示如何使用PaginatedItemsBuilder

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

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

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

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

class _MyHomePageState extends State<MyHomePage> {
  final PaginatedDataSource<int> _dataSource = PaginatedDataSource<int>(
    pageLoadFuture: (pageKey) async {
      // 模拟从服务器获取数据,这里我们简单返回一个列表
      List<int> items = List.generate(20, (index) => pageKey * 20 + index + 1);
      return PaginatedResultList<int>(data: items);
    },
    errorWidget: (context, error, stackTrace) {
      return Center(child: Text('Error: $error'));
    },
  );

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Paginated Items Builder Demo'),
      ),
      body: PaginatedItemsBuilder<int>(
        dataSource: _dataSource,
        itemBuilder: (context, item, index) {
          return ListTile(
            title: Text('Item $item'),
          );
        },
        loadingBuilder: (context) {
          return Center(child: CircularProgressIndicator());
        },
        noItemsFoundBuilder: (context) {
          return Center(child: Text('No items found.'));
        },
        pageErrorBuilder: (context, error, stackTrace) {
          return Center(child: Text('Page load error: $error'));
        },
      ),
    );
  }
}

在这个示例中:

  1. PaginatedDataSource负责分页数据的加载。pageLoadFuture是一个异步函数,它根据当前的页码(pageKey)返回一页数据。在这个例子中,我们简单地生成了一个包含20个整数的列表,每个整数都是基于页码和索引计算的。

  2. PaginatedItemsBuilder是主要的widget,它接受一个dataSource和几个builder函数:

    • itemBuilder用于构建每一项。
    • loadingBuilder用于显示加载指示器。
    • noItemsFoundBuilder当没有找到任何项目时显示。
    • pageErrorBuilder当加载页面数据时发生错误时显示。

这个示例展示了如何使用paginated_items_builder插件以分页的方式加载和显示数据。你可以根据自己的需求调整pageLoadFuture的实现,以便从实际的API获取数据。

回到顶部