Flutter下拉刷新与上拉加载插件easy_refresh的使用
Flutter下拉刷新与上拉加载插件easy_refresh的使用
flutter_easy_refresh
英文文档 | 中文文档
EasyRefresh
正如其名,可以在Flutter应用程序中轻松实现下拉刷新和上拉加载功能。它几乎支持所有可滚动的小部件,功能类似于Android的SmartRefreshLayout,并吸收了许多第三方库的优点。EasyRefresh
集成了多种风格的Header和Footer,但并不局限于此,你可以轻松自定义它们。利用Flutter强大的动画功能,即使是一个简单的控件也能完成复杂的操作。EasyRefresh
的目标是为Flutter创建一个强大、稳定且成熟的下拉刷新框架。
在线演示
APK下载
API参考
Features
- 支持所有可滚动的小部件
- 滚动物理范围,精确匹配可滚动小部件
- 集成多种炫酷的Header和Footer
- 支持自定义样式以实现各种动画效果
- 支持下拉刷新、上拉加载(可以通过控制器触发和完成)
- 支持指示器位置设置,结合监听器可以放置在任意位置
- 支持页面启动时刷新,并自定义视图
- 支持安全区域,避免遮挡
- 自定义滚动参数,允许列表具有不同的滚动反馈和惯性
示例代码
以下是一个完整的示例demo,展示了如何使用EasyRefresh
实现下拉刷新和上拉加载:
import 'package:flutter/material.dart';
import 'package:easy_refresh/easy_refresh.dart';
void main() => runApp(const MyApp());
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return const MaterialApp(
title: 'EasyRefresh',
home: HomePage(),
);
}
}
class HomePage extends StatefulWidget {
const HomePage({Key? key}) : super(key: key);
@override
State<HomePage> createState() => _HomePageState();
}
class _HomePageState extends State<HomePage> {
int _count = 10;
late EasyRefreshController _controller;
@override
void initState() {
super.initState();
_controller = EasyRefreshController(
controlFinishRefresh: true,
controlFinishLoad: true,
);
}
@override
void dispose() {
_controller.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('EasyRefresh'),
),
body: EasyRefresh(
controller: _controller,
header: const ClassicHeader(),
footer: const ClassicFooter(),
onRefresh: () async {
await Future.delayed(const Duration(seconds: 2));
if (!mounted) {
return;
}
setState(() {
_count = 10;
});
_controller.finishRefresh();
_controller.resetFooter();
},
onLoad: () async {
await Future.delayed(const Duration(seconds: 2));
if (!mounted) {
return;
}
setState(() {
_count += 5;
});
_controller.finishLoad(
_count >= 20 ? IndicatorResult.noMore : IndicatorResult.success);
},
child: ListView.builder(
itemBuilder: (context, index) {
return Card(
child: Container(
alignment: Alignment.center,
height: 80,
child: Text('${index + 1}'),
),
);
},
itemCount: _count,
),
),
);
}
}
使用说明
1. 默认构造函数
在子作用域中,所有滚动组件将共享一个物理属性。如果有嵌套滚动,使用EasyRefresh.builder
或通过ScrollConfiguration
设置作用域。
EasyRefresh(
onRefresh: () async {
// 刷新逻辑
},
onLoad: () async {
// 加载逻辑
},
child: ListView(),
);
2. Builder构造函数
EasyRefresh.builder(
onRefresh: () async {
// 刷新逻辑
return IndicatorResult.success;
},
onLoad: () async {
// 加载逻辑
},
childBuilder: (context, physics) {
return ListView(
physics: physics,
);
},
);
3. 指示器位置
EasyRefresh(
header: Header(
position: IndicatorPosition.locator,
),
footer: Footer(
position: IndicatorPosition.locator,
),
onRefresh: () async {
// 刷新逻辑
},
onLoad: () async {
// 加载逻辑
return IndicatorResult.noMore;
},
child: CustomScrollView(
slivers: [
SliverAppBar(),
const HeaderLocator.sliver(),
// 其他Sliver组件
const FooterLocator.sliver(),
],
),
);
4. 使用控制器
EasyRefreshController _controller = EasyRefreshController(
controlFinishRefresh: true,
controlFinishLoad: true,
);
// ...
EasyRefresh(
controller: _controller,
onRefresh: () async {
// 刷新逻辑
_controller.finishRefresh();
_controller.resetFooter();
},
onLoad: () async {
// 加载逻辑
_controller.finishLoad(IndicatorResult.noMore);
},
// ...
);
// 调用刷新或加载
_controller.callRefresh();
_controller.callLoad();
5. 指定Header和Footer
EasyRefresh(
header: MaterialHeader(),
footer: MaterialFooter(),
child: ListView(),
// ...
);
// 全局设置
EasyRefresh.defaultHeaderBuilder = () => ClassicHeader();
EasyRefresh.defaultFooterBuilder = () => ClassicFooter();
6. NestedScrollView
EasyRefresh.builder(
header: MaterialHeader(
clamping: true,
),
onRefresh: () async {
// 刷新逻辑
},
onLoad: () async {
// 加载逻辑
},
childBuilder: (context, physics) {
return NestedScrollView(
physics: physics,
body: ListView(
physics: physics,
);
);
},
);
// 或者
EasyRefresh.builder(
header: MaterialHeader(
clamping: true,
position: IndicatorPosition.locator,
),
onRefresh: () async {
// 刷新逻辑
},
onLoad: () async {
// 加载逻辑
},
childBuilder: (context, physics) {
return NestedScrollView(
physics: physics,
headerSliverBuilder: (context, innerBoxIsScrolled) {
return [
const HeaderLocator.sliver(clearExtent: false),
// 其他Sliver组件
];
},
body: ListView(
physics: physics,
);
);
},
);
参与贡献
如果你有好的建议和改进,请随时贡献你的代码。如果你有一些非常酷的样式,分享给大家就更棒了!
感谢所有已经为此项目做出贡献的人!
QQ群 - 554981921
这个群不仅解决EasyRefresh
的问题,任何Flutter相关的问题都可以讨论。只要时间允许,群主会帮助你一起解决问题。
致谢
许可证
MIT License
Copyright © 2018 xuelongqy
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
更多关于Flutter下拉刷新与上拉加载插件easy_refresh的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
更多关于Flutter下拉刷新与上拉加载插件easy_refresh的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
当然,以下是如何在Flutter中使用easy_refresh
插件来实现下拉刷新和上拉加载功能的示例代码。
首先,确保你已经在pubspec.yaml
文件中添加了easy_refresh
依赖:
dependencies:
flutter:
sdk: flutter
easy_refresh: ^2.2.10 # 请根据需要检查最新版本号
然后运行flutter pub get
来安装依赖。
接下来,创建一个Flutter应用,并在其中使用EasyRefresh
组件。以下是一个完整的示例:
import 'package:flutter/material.dart';
import 'package:easy_refresh/easy_refresh.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'EasyRefresh Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: MyHomePage(),
);
}
}
class MyHomePage extends StatefulWidget {
@override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
List<String> dataList = List.generate(20, (index) => "Item ${index + 1}");
bool isLoading = false;
bool hasMore = true;
void _onRefresh() async {
// 模拟网络请求延迟
await Future.delayed(Duration(seconds: 2));
setState(() {
dataList = List.generate(20, (index) => "Refreshed Item ${index + 1}");
isLoading = false;
});
}
void _onLoad() async {
// 模拟网络请求延迟
if (hasMore) {
await Future.delayed(Duration(seconds: 2));
setState(() {
dataList.addAll(List.generate(10, (index) => "Loaded Item ${dataList.length + index + 1}"));
if (dataList.length >= 50) {
hasMore = false; // 假设最多加载到50条数据
}
isLoading = false;
});
}
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('EasyRefresh Demo'),
),
body: EasyRefresh(
onRefresh: _onRefresh,
onLoad: _onLoad,
isFirstRefresh: true,
isFirstLoad: true,
loadingText: "Loading...",
noMoreText: "No More Data",
refreshFooter: ClassicsFooter(),
refreshHeader: ClassicsHeader(),
child: ListView.builder(
itemCount: dataList.length,
itemBuilder: (context, index) {
return ListTile(
title: Text(dataList[index]),
);
},
),
),
);
}
}
在这个示例中:
EasyRefresh
组件用于包裹ListView
,它提供了下拉刷新和上拉加载的功能。onRefresh
和onLoad
回调分别处理下拉刷新和上拉加载的逻辑。ClassicsFooter
和ClassicsHeader
是easy_refresh
提供的默认刷新和加载指示器,你可以根据需要自定义它们。ListView.builder
用于动态生成列表项。
这个示例演示了如何使用easy_refresh
插件来实现下拉刷新和上拉加载功能,并展示了如何管理加载状态和数据。