实践是知识的母亲,知识是生活的明灯。这篇文章主要讲述Flutter 专题16 图解 ListView下拉刷新与上拉加载#yyds干货盘点#相关的知识,希望能为你提供帮助。
小菜上次学 ListView 时,只学习了一下异步请求数据加载新闻和 Loading 等待的小知识点,但对于新闻列表数据的更新和加载更多是必不可少的,而实现【下拉刷新】与【上划加载更多】的方式有很多种,今天小菜整理一下使用三方库 flutter_refresh 来实现列表的数据更新。
小菜也是再偶然间看到有大神用到这个三方库的,小菜想要尝试的原因主要是因为一是因为 flutter_refresh 集成很简单,不用单独写头部样式和底部加载时的 loading 等;二是小菜技术太有限,对 Flutter 的未知有太多,想多尝试几种方式。
文章图片
集成方式
- pubspec.yaml 中 添加 flutter_refresh : ^0.0.2,并同步 packages get;
- 在相应的 .dart 文件中添加引用 import package:flutter_refresh/flutter_refresh.dart;
- 数据加载时暂时不用 ListView 变更为 new Refresh,小菜主要是处理 onHeaderRefresh 下拉刷新 和 onFooterRefresh 底部刷新 两个方法中的数据处理。小菜的测试接口需要根据每一页的最后一个新闻ID 和 整个的新闻数量为参数值进行处理。
文章图片
// 顶部刷新
Future<
Null>
onHeaderRefresh() {
return new Future.delayed(new Duration(seconds: 2), () {
setState(() {
rowNumber = 0;
lastFileID = 0;
newsListBean = null;
getNewsData(lastFileID, rowNumber);
});
});
}
// 底部刷新
Future<
Null>
onFooterRefresh() async {
return new Future.delayed(new Duration(seconds: 2), () {
setState(() {
getNewsData(lastFileID, rowNumber);
});
});
}
// 接口数据处理
getNewsData(var lastID, var rowNum) async {
await http
.get(
https://...?lastFileID=${lastID}&
rowNumber=${rowNum})
.then((response) {
if (response.statusCode == 200) {
var jsonRes = json.decode(response.body);
newsListBean = NewsListBean(jsonRes);
if (lastID == 0 &
&
rowNum==0 &
&
dataItems != null) {
dataItems.clear();
}
setState(() {
if (newsListBean != null &
&
newsListBean.list != null &
&
newsListBean.list.length >
0) {
for (int i = 0;
i <
newsListBean.list.length;
i++) {
dataItems.add(newsListBean.list[i]);
}
lastFileID = newsListBean.list[newsListBean.list.length - 1].fileID
.toString();
rowNumber += newsListBean.list.length;
} else {}
});
}
});
}Widget childFreshWidget() {
Widget childFreWi;
if (dataItems != null &
&
dataItems.length != 0) {
childFreWi = new Padding(
padding: EdgeInsets.all(6.0),
child: new Refresh(
onFooterRefresh: onFooterRefresh,
onHeaderRefresh: onHeaderRefresh,
childBuilder: (BuildContext context,
{ScrollController controller, ScrollPhysics physics}) {
return new Container(
child: new ListView.builder(
physics: physics,
controller: controller,
itemCount: rowNumber,
itemBuilder: (context, item) {
return buildListData(context, dataItems[item]);
},
));
},
),
);
} else {
childFreWi = new Stack(
children: <
Widget>
[
new Padding(
padding: new EdgeInsets.fromLTRB(0.0, 0.0, 0.0, 35.0),
child: new Center( child: SpinKitFadingCircle( color: Colors.blueAccent, size: 30.0, ), ),
),
new Padding(
padding: new EdgeInsets.fromLTRB(0.0, 35.0, 0.0, 0.0),
child: new Center( child: new Text(正在加载中,莫着急哦~), ),
),
],
);
}
return childFreWi;
}
文章图片
文章图片
问题小结
小菜在测试过程中遇到了很多的小问题,现在逐一整理一下。
问题一:初始化进入页面后,加载完第一页之后刷新数据不加载,第二次刷新数据才加载,且加载的是上一次刷新的数据? 解决方式:
- 进入页面时调用数据接口 initState(),为了保证第一次正常加载;
- 在 getNewsData() 中一定一定要添加 setState(() {});
小菜在测试时,每次刷新接口都会正常调用,但是都是第二次刷新才加载第一次刷新的数据,接口是正常的,但是数据总是慢一拍,小菜测试发现因为没有用 setState(() {});
以后一定要注意,这样才可以实时进行更新。
问题二:下拉刷新过程中,接口数据重复加载?
解决方式:
小菜目前还没有涉及缓存等方面的,单纯的一个下拉刷新应该是重新调用初始的接口,首先要清空列表,不然接口数据重复实实在在会出现的。
Future< Null> onHeaderRefresh() { return new Future.delayed(new Duration(seconds: 2), () { setState(() { rowNumber = 0; lastFileID = 0; if (dataItems != null) { dataItems.clear(); } getNewsData(lastFileID, rowNumber); }); }); }
问题三:根据问题二的解决方案,显示正常,但是运行时 Log 报错,提示 Widget 已创建?
文章图片
解决方案: 小菜测试了很久,把这个判断列表制空从 onHeaderRefresh() 中移到数据处理的 getNewsData() 方法中,虽然不是非常理解,但是问题可以正常解决,小菜的理解是 onHeaderRefresh() 中处理的是数据和 Widget,而小菜自己的方法中是单纯的数据处理。
if (lastID == 0 &
&
rowNum==0 &
&
dataItems != null) {
dataItems.clear();
}
【Flutter 专题16 图解 ListView下拉刷新与上拉加载#yyds干货盘点#】 小菜刚接触 Flutter 时间不长,还有很多不清楚和不理解的地方,如果又不对的地方还希望多多指出。
推荐阅读
- SpringBoot加email服务,你说有没有搞头()
- NLP 中文形近字相似度算法开源实现
- #yyds干货盘点# 泛型通配符
- 手把手教你用Python网络爬虫进行多线程采集高清游戏壁纸
- 从冰箱装大象到女娲造人,带你彻底吃透Python面向对象编程
- 一次完整的JVM NativeMemoryTracking 堆外内存泄露分析
- rpm 命令 – RPM软件包管理器
- #yyds干货盘点# MyBatis-Plus——代码生成器(3.5.1+版本)
- WordPress主题中的Bootstrap无法在浏览器中渲染