Flutter下拉刷新及专业功能插件pull_to_refresh_pro的使用
Flutter下拉刷新及专业功能插件pull_to_refresh_pro的使用
介绍
pull_to_refresh_pro
是一个提供上拉加载和下拉刷新的组件, 同时支持Android和iOS。
特性
- 提供上拉加载和下拉刷新
- 几乎适合所有部件
- 提供全局设置默认指示器和属性
- 提供多种比较常用的指示器
- 支持Android和iOS默认滑动引擎,可限制越界距离, 打造自定义弹性动画, 速度, 阻尼等。
- 支持水平和垂直刷新, 同时支持翻转列表(四个方向)
- 提供多种刷新指示器风格: 跟随, 不跟随, 位于背部, 位于前部, 提供多种加载更多风格
- 提供二楼刷新, 可实现类似淘宝二楼, 微信二楼, 携程二楼
- 允许关联指示器存放在Viewport外部, 即朋友圈刷新效果
用法
- 添加依赖到
pubspec.yaml
dependencies:
pull_to_refresh_pro: ^0.0.1
- 导入库
import 'package:pull_to_refresh_pro/pull_to_refresh_pro.dart';
- 简单例子
List<String> items = ["1", "2", "3", "4", "5", "6", "7", "8"];
RefreshController _refreshController = RefreshController(initialRefresh: false);
void _onRefresh() async {
// 监听网络请求
await Future.delayed(Duration(milliseconds: 1000));
// 如果失败, 使用 refreshFailed()
_refreshController.refreshCompleted();
}
void _onLoading() async {
// 监听网络请求
await Future.delayed(Duration(milliseconds: 1000));
// 如果失败, 使用 loadFailed(), 如果无数据返回, 使用 LoadNodata()
items.add((items.length + 1).toString());
if (mounted)
setState(() {});
_refreshController.loadComplete();
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: SmartRefresher(
enablePullDown: true,
enablePullUp: true,
header: WaterDropHeader(),
footer: CustomFooter(
builder: (BuildContext context, LoadStatus mode) {
Widget body;
if (mode == LoadStatus.idle) {
body = Text("上拉加载");
} else if (mode == LoadStatus.loading) {
body = CupertinoActivityIndicator();
} else if (mode == LoadStatus.failed) {
body = Text("加载失败!点击重试!");
} else if (mode == LoadStatus.canLoading) {
body = Text("松手, 加载更多!");
} else {
body = Text("没有更多数据了!");
}
return Container(
height: 55.0,
child: Center(child: body),
);
},
),
controller: _refreshController,
onRefresh: _onRefresh,
onLoading: _onLoading,
child: ListView.builder(
itemBuilder: (c, i) => Card(child: Center(child: Text(items[i]))),
itemExtent: 100.0,
itemCount: items.length,
),
),
);
}
- 全局配置
RefreshConfiguration
, 配置子树下的所有SmartRefresher
表现, 一般存放于MaterialApp
的根部, 用法和ScrollConfiguration
是类似的。
RefreshConfiguration(
headerBuilder: () => WaterDropHeader(), // 配置默认头部指示器
footerBuilder: () => ClassicFooter(), // 配置默认底部指示器
headerTriggerDistance: 80.0, // 头部触发刷新的越界距离
springDescription: SpringDescription(stiffness: 170, damping: 16, mass: 1.9), // 自定义回弹动画
maxOverScrollExtent: 100, // 头部最大可以拖动的范围
maxUnderScrollExtent: 0, // 底部最大可以拖动的范围
enableScrollWhenRefreshCompleted: true, // 在刷新完成后是否可以继续滚动
enableLoadingWhenFailed: true, // 在加载失败的状态下, 用户仍然可以通过手势上拉来触发加载更多
hideFooterWhenNotFull: false, // 当Viewport不满一屏时, 禁用上拉加载更多功能
enableBallisticLoad: true, // 可以通过惯性滑动触发加载更多
child: MaterialApp(
// 其他配置...
),
);
- 1.5.6 新增国际化处理特性, 你可以在
MaterialApp
或者CupertinoApp
追加如下代码:
MaterialApp(
localizationsDelegates: [
// 这行是关键
RefreshLocalizations.delegate,
GlobalWidgetsLocalizations.delegate,
GlobalMaterialLocalizations.delegate
],
supportedLocales: [
const Locale('en'),
const Locale('zh'),
],
localeResolutionCallback: (Locale locale, Iterable<Locale> supportedLocales) {
return locale;
},
);
对SmartRefresher里child详细说明
自1.4.3, child
属性从 ScrollView
转变为 Widget
, 但是这并不意味着对于所有 Widget
处理是一样的。SmartRefresher
内部实现机制并非是类似于 NestedScrollView
。
这里的处理机制分为两个大类:
- 第一类是继承于
ScrollView
的那一类组件, 目前来说, 就只有这三种:ListView
,GridView
,CustomScrollView
。 - 第二类是非继承于
ScrollView
的那类组件, 一般是存放空视图, 非滚动视图(非滚动转化为滚动),PageView
, 无需你自己通过LayoutBuilder
估计高度。
对于第一类的处理机制是从内部"非法"取出 slivers
。第二类, 则是把 child
直接放进类似于 SliverToBoxAdapter
。通过前后拼接 header
和 footer
组成 slivers
, 然后 SmartRefresher
内部把 slivers
放进 CustomScrollView
。
更多
- 属性文档 或者 Api/Doc
- 自定义指示器
- 指示器内部属性介绍
- 更新日志
- 注意地方
- 常见问题
暂时存在的问题
- 关于配合
NestedScrollView
一起使用, 会出现很多奇怪的现象, 当你下滑然后快速上滑, 它会出现跳动, 主要是NestedScrollView
没有考虑到在BouncingScrollPhysics
下的越界问题, 相关flutter
issue: 34316, 33367, 29264, 这个问题只能等待flutter
修复。 SmartRefresher
不具有向子树下的ScrollView
注入刷新功能, 也就是说如果直接把AnimatedList
,RecordableListView
放在child
结点是不行的, 这个问题我尝试过很多个方法都失败了, 由于实现原理, 我必须得在slivers
头部和尾部追加, 实际上, 这个问题也不是我组件的问题, 比如说AnimatedList
, 假如我要结合AnimatedList
和GridView
一起使用是没办法的, 唯有把AnimatedList
转换为SliverAnimatedList
才能解决。目前呢, 面对这种问题的话, 我已经有临时的解决方案, 但有点麻烦, 要重写它内部的代码, 然后在ScrollView
外部增加SmartRefresher
。
感谢
开源协议
MIT License
Copyright (c) 2018 Jpeng
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下拉刷新及专业功能插件pull_to_refresh_pro的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
1 回复