Flutter分页管理插件pagination_manager的使用
Flutter分页管理插件pagination_manager的使用
📦 Pagination Manager
这是一个强大且灵活的Flutter包,用于处理带有内置状态管理支持的分页数据。可以轻松实现无限滚动列表,同时减少样板代码。
✨ 特性
- 🚀 简单易用的分页管理
- 💪 内置Bloc/Cubit状态管理支持
- 🎯 框架无关 - 适用于任何状态管理解决方案
- 🔄 下拉刷新支持
- ⚡ 带有自动状态管理的懒加载
- 🎨 可定制的加载和错误状态
- 📱 响应式和自适应设计
📋 安装
在你的pubspec.yaml
中添加以下依赖:
dependencies:
pagination_manager: ^1.0.0
然后导入:
import 'package:pagination_manager/pagination_manager.dart';
🚀 快速开始
1. 创建一个Repository
首先,实现PaginatedRepository
接口:
class MyDataRepository implements PaginatedRepository<MyData> {
@override
Future<PaginationResult<MyData>> fetchPaginatedItems(int page, int limitPerPage) async {
try {
final response = await api.fetchData(page: page, limit: limitPerPage);
return PaginationResult.success(response);
} catch (e) {
return PaginationResult.failure(e.toString());
}
}
}
2. 初始化PaginationManager
final paginationManager = PaginationManager<MyData>(
repository: MyDataRepository(),
limitPerPage: 20,
);
3. 使用PaginatedManagerList(推荐)
最简单的方式是使用PaginatedManagerList
来实现带有完整状态管理的分页:
PaginatedManagerList<MyData>(
paginationManager: paginationManager,
itemBuilder: (context, index, items) {
final item = items[index];
return ListTile(
title: Text(item.title),
);
},
);
这将自动处理:
- 自动无限滚动
- 加载状态
- 错误处理与可自定义的重试按钮
- 下拉刷新
- 重试机制
- 空状态处理
自定义PaginatedManagerList
PaginatedManagerList<MyData>(
paginationManager: paginationManager,
itemBuilder: (context, index, items) => MyItemWidget(item: items[index]),
// Customization options
scrollThreshold: 0.8, // 在80%滚动时触发分页
showRefreshIndicator: true, // 启用下拉刷新
showRetryButton: true, // 显示错误时的重试按钮
emptyItemsText: 'No items found', // 自定义空状态消息
retryText: 'Try Again', // 自定义重试按钮文本
scrollDirection: Axis.vertical, // 滚动方向
initialLoadingWidget: MyLoadingWidget(), // 自定义初始加载小部件
loadingPaginationWidget: MyLoadingIndicator(), // 自定义分页加载指示器
emptyItemsWidget: MyEmptyState(), // 自定义空状态小部件
whenErrMessageFromPagination: (message) {
// 处理分页错误
showSnackBar(message);
},
fetchItemsFailureWidget: (errorMessage) {
// 自定义错误小部件
return MyErrorWidget(message: errorMessage);
},
// 样式设置
errorTextStyle: TextStyle(color: Colors.red),
retryTextStyle: TextStyle(color: Colors.blue),
retryButtonStyle: ButtonStyle(...),
);
4. 替代方案:手动实现
如果你需要更多控制,可以直接使用PaginatedList
小部件:
PaginatedList<MyData>(
paginationManager: paginationManager,
loadingFromPaginationState: false,
fetchNextPage: () => paginationManager.fetchNextPage(),
itemBuilder: (context, index, items) {
final item = items[index];
return ListTile(
title: Text(item.title),
);
},
retryText: 'Try Again',
onRefresh: () async {
paginationManager.reset();
await paginationManager.fetchNextPage();
},
);
📖 API参考
PaginatedManagerList
属性 | 类型 | 描述 |
---|---|---|
paginationManager | PaginationManager | 必填 - 分页逻辑管理器 |
itemBuilder | Widget? Function(BuildContext, int, List<T>) | 必填 - 列表项构建器 |
scrollThreshold | double | 触发分页的阈值(0.0到1.0) |
showRefreshIndicator | bool | 启用/禁用下拉刷新 |
showRetryButton | bool | 显示/隐藏错误时的重试按钮 |
emptyItemsText | String | 空状态文本 |
retryText | String | 重试按钮文本 |
loadingPaginationWidget | Widget? | 自定义加载指示器 |
whenErrMessageFromPagination | Function(String)? | 分页错误处理器 |
fetchItemsFailureWidget | Widget Function(String)? | 自定义错误小部件构建器 |
errorTextStyle | TextStyle? | 错误消息样式 |
retryTextStyle | TextStyle? | 重试按钮文本样式 |
retryButtonStyle | ButtonStyle? | 重试按钮样式 |
PaginationManager
属性 | 类型 | 描述 |
---|---|---|
repository | PaginatedRepository | 数据获取仓库 |
limitPerPage | int | 每页项目数量 |
items | List<T> | 当前项目列表 |
hasMore | bool | 是否还有更多项目 |
isLoading | bool | 加载状态 |
🤝 贡献
欢迎贡献!请随时提交Pull Request。
📄 许可证
本项目采用MIT许可证 - 详情见LICENSE文件。
示例代码
以下是pagination_manager
插件的一个完整示例,展示如何在一个简单的应用中使用它。
// example/lib/main.dart
import 'package:flutter/material.dart';
import 'package:pagination_manager/pagination_manager.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Pagination Manager Example',
theme: ThemeData(
colorScheme: ColorScheme.fromSeed(seedColor: Colors.blue),
useMaterial3: true,
),
home: const PostListScreen(),
);
}
}
// 示例数据模型
class Post {
final int id;
final String title;
final String body;
Post({
required this.id,
required this.title,
required this.body,
});
factory Post.fromJson(Map<String, dynamic> json) {
return Post(
id: json['id'],
title: json['title'],
body: json['body'],
);
}
}
// 示例仓库实现
class PostsRepository implements PaginatedRepository<Post> {
@override
Future<PaginationResult<Post>> fetchPaginatedItems(
int page, int limitPerPage) async {
try {
// 模拟API延迟
await Future.delayed(const Duration(seconds: 2));
// 计算分页的起始和结束索引
final startIndex = (page - 1) * limitPerPage;
final endIndex = startIndex + limitPerPage;
// 模拟API响应的虚拟数据
final List<Post> posts = List.generate(
100,
(index) => Post(
id: index + 1,
title: 'Post ${index + 1}',
body: 'This is the body of post ${index + 1}.',
),
);
// 模拟分页逻辑
// 截取列表以获取分页项目
final paginatedPosts = posts.sublist(
startIndex,
endIndex > posts.length ? posts.length : endIndex,
);
return PaginationResult.success(paginatedPosts);
} catch (e) {
//return PaginationResult.failure(e.toString());
return const PaginationResult.failure('An error while fetching.');
}
}
}
class PostListScreen extends StatefulWidget {
const PostListScreen({super.key});
@override
State<PostListScreen> createState() => _PostListScreenState();
}
class _PostListScreenState extends State<PostListScreen> {
late final PaginationManager<Post> _paginationManager;
@override
void initState() {
super.initState();
_paginationManager = PaginationManager<Post>(
repository: PostsRepository(),
limitPerPage: 10,
);
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Posts'),
),
body: PaginatedManagerList<Post>(
paginationManager: _paginationManager,
itemBuilder: (context, index, items) {
final post = items[index];
return Card(
margin: const EdgeInsets.symmetric(horizontal: 16, vertical: 8),
child: ListTile(
title: Text(
post.title,
style: const TextStyle(fontWeight: FontWeight.bold),
),
subtitle: Text(
post.body,
maxLines: 2,
overflow: TextOverflow.ellipsis,
),
),
);
},
// 自定义分页体验
scrollThreshold: 0.8,
showRefreshIndicator: true,
emptyItemsText: 'No posts available',
retryText: 'Try Again',
// 处理分页错误
whenErrMessageFromPagination: (message) {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(content: Text('Error: $message')),
);
},
),
);
}
}
通过上述代码,您可以快速搭建一个具有分页功能的应用,并根据需要进行自定义和扩展。希望这对您有所帮助!
更多关于Flutter分页管理插件pagination_manager的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
更多关于Flutter分页管理插件pagination_manager的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
当然,下面是一个关于如何在Flutter中使用pagination_manager
插件进行分页管理的代码案例。pagination_manager
插件可以帮助你轻松实现分页加载数据的功能。
首先,你需要在pubspec.yaml
文件中添加pagination_manager
依赖:
dependencies:
flutter:
sdk: flutter
pagination_manager: ^x.y.z # 替换为最新版本号
然后运行flutter pub get
来安装依赖。
接下来是一个简单的示例,展示如何使用pagination_manager
进行分页加载:
import 'package:flutter/material.dart';
import 'package:pagination_manager/pagination_manager.dart';
import 'dart:async';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: PaginationScreen(),
);
}
}
class PaginationScreen extends StatefulWidget {
@override
_PaginationScreenState createState() => _PaginationScreenState();
}
class _PaginationScreenState extends State<PaginationScreen> with AutomaticKeepAliveClientMixin {
final PaginationController<int> paginationController = PaginationController(pageLimit: 20);
List<int> items = [];
@override
bool get wantKeepAlive => true;
@override
void initState() {
super.initState();
fetchData();
}
Future<void> fetchData() async {
// 模拟网络请求延迟
await Future.delayed(Duration(seconds: 1));
// 获取当前页的数据
List<int> pageData = List.generate(paginationController.pageLimit, (index) {
return items.length + index + 1;
});
// 更新状态
setState(() {
items.addAll(pageData);
});
// 通知分页控制器数据已加载
paginationController.notifyDataLoaded();
}
@override
Widget build(BuildContext context) {
super.build(context);
return Scaffold(
appBar: AppBar(
title: Text('Pagination Manager Example'),
),
body: PaginationView<int>(
controller: paginationController,
onPageRequested: (page) async {
// 加载新页面的数据
await fetchData();
},
itemBuilder: (context, item, index) {
return ListTile(
title: Text('Item ${item}'),
);
},
),
);
}
}
代码解释
-
依赖导入和安装:
- 在
pubspec.yaml
文件中添加pagination_manager
依赖。
- 在
-
分页控制器:
PaginationController<int>
用于管理分页状态,这里我们设置每页加载20个数据项。
-
数据加载:
fetchData
方法模拟了一个网络请求,延迟1秒后生成当前页的数据并添加到items
列表中。- 使用
setState
更新UI。 - 调用
paginationController.notifyDataLoaded()
通知分页控制器数据已加载完成。
-
分页视图:
PaginationView<int>
用于显示分页数据。onPageRequested
回调在请求新页面时被调用,这里我们调用fetchData
方法加载新页面的数据。itemBuilder
用于构建每个数据项的UI。
这个示例展示了如何使用pagination_manager
插件进行基本的分页管理。你可以根据具体需求修改和扩展这个示例。