pull_to_refresh 是flutter常用的列表刷新加载组件,因为项目中通常列表是比较多的,所以便封装了一个类,把需要复用到的代码整合起来,一下是我项目中对pull_to_refresh 封装的代码:
import 'package:flutter/material.dart';
import 'package:flutter_jtcenter/color_style.dart';
import 'package:lottie/lottie.dart';
import 'package:pull_to_refresh/pull_to_refresh.dart';
class Refresh {
static header({type: 1}) {
Widget load = Column(children: [
Container(
width: 79,
height: 15,
margin: EdgeInsets.only(top: 5, bottom: 8.0),
child: Image.asset(
type == 0 ? 'images/logo.png' : 'images/logo-red.png',
fit: BoxFit.fill,
),
),
Container(
alignment: Alignment.center,
width: 150.0,
// height: 30.0,
child: Lottie.asset(
'assets/lottie/Loading-${type == 0 ? 'white' : 'red'}.json'),
)
]);
return CustomHeader(
builder: (context, mode) {
Widget body;
if (mode == RefreshStatus.idle) {
body = load;
} else if (mode == RefreshStatus.refreshing) {
body = load;
} else if (mode == RefreshStatus.canRefresh) {
body = load;
} else if (mode == RefreshStatus.completed) {
body = load;
} else if (mode == RefreshStatus.failed) {
body = Text(
'网络异常,请刷新重试',
style: TextStyle(
fontSize: 14,
color: ColorStyle.tipsColor,
),
);
}
return Container(
height: 60.0,
child: Center(
child: body,
),
);
},
);
}
static footer({int len: 1}) {
var sty = TextStyle(color: ColorStyle.tipsColor);
return CustomFooter(
builder: (BuildContext context, LoadStatus mode) {
Widget body;
if (mode == LoadStatus.idle) {
body = Text("上拉加载", style: sty);
} else if (mode == LoadStatus.loading) {
body = Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Image.asset(
'images/loading.gif',
fit: BoxFit.fill,
width: 15,
height: 15,
),
SizedBox(width: 5),
Text("加载中...", style: sty)
],
);
} else if (mode == LoadStatus.failed) {
body = Text("加载失败!", style: sty);
} else if (mode == LoadStatus.canLoading) {
body = Text("松手,加载更多!", style: sty);
} else {
body = Text(len == 0 ? "暂无数据" : "没有更多数据了!", style: sty);
}
return Container(
height: 55.0,
child: Center(child: body),
);
},
);
}
static fail() {
return Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Image.asset(
'images/fail.png',
width: 100.0,
height: 100.0,
fit: BoxFit.fill,
),
Text(
'网络异常,请刷新重试',
style: TextStyle(
fontSize: 14,
color: ColorStyle.tipsColor,
),
),
],
);
}
static nodata() {
return Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Image.asset(
'images/ico_nodata.png',
width: 100.0,
height: 100.0,
fit: BoxFit.fill,
),
// Text(
// '暂无数据',
// style: TextStyle(
// fontSize: 14,
// color: ColorStyle.tipsColor,
// ),
// ),
],
);
}
static setStatus(res, _controller, fn, err) {
if (res["code"] == 1) {
if (res['data'] != null) {
int total = res['data']['total'];
List orderData = res['data']['records'];
fn(orderData, total);
if (_controller.isRefresh) {
// 下拉刷新
_controller.refreshCompleted();
if (orderData.length == total) {
_controller.loadNoData();
} else {
_controller.loadComplete();
}
} else if (_controller.isLoading) {
// 上拉加载
if (orderData.length == total) {
_controller.loadNoData();
} else {
_controller.loadComplete();
}
} else {
if (orderData.length == total) {
_controller.loadNoData();
} else {
_controller.loadComplete();
}
}
}
} else {
if (_controller.isRefresh) {
// 是下拉刷新
_controller.refreshFailed();
} else {
_controller.loadFailed();
}
err();
}
}
}
lottie 是一个loading组件,这里就不做介绍了,有兴趣的可以单独了解一下。
使用如下:
包含了下拉刷新的header样式以及上拉加载的footer样式,并对列表加载成功、失败、数据全部加载完毕做了处理。
setStatus方法是对接口返回的数据做相应的处理,接受的参数中,res是接口返回的数据,更加res['code']来判断是否成功或失败,_controller是下拉组件的控制器,根据它来判断当前操作是上拉还是下拉,(_controller.isLoading | _controller.isRefresh)。
footer方法传入一个len参数,此参数是列表的长度,用来判断是显示‘暂无数据’还是列表数据以加载完全部。
fail方法返回失败布局样式,nodata方法返回暂无数据布局样式。