pull_to_refresh 是flutter常用的列表刷新加載組件,因?yàn)轫?xiàng)目中通常列表是比較多的,所以便封裝了一個(gè)類,把需要復(fù)用到的代碼整合起來,一下是我項(xiàng)目中對(duì)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(
????????????'網(wǎng)絡(luò)異常,請(qǐng)刷新重試',
????????????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???"暫無數(shù)據(jù)"?:?"沒有更多數(shù)據(jù)了!",?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(
??????????'網(wǎng)絡(luò)異常,請(qǐng)刷新重試',
??????????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(
????????//???'暫無數(shù)據(jù)',
????????//???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 是一個(gè)loading組件,這里就不做介紹了,有興趣的可以單獨(dú)了解一下。
使用如下:

包含了下拉刷新的header樣式以及上拉加載的footer樣式,并對(duì)列表加載成功、失敗、數(shù)據(jù)全部加載完畢做了處理。
setStatus方法是對(duì)接口返回的數(shù)據(jù)做相應(yīng)的處理,接受的參數(shù)中,res是接口返回的數(shù)據(jù),更加res['code']來判斷是否成功或失敗,_controller是下拉組件的控制器,根據(jù)它來判斷當(dāng)前操作是上拉還是下拉,(_controller.isLoading | _controller.isRefresh)。
footer方法傳入一個(gè)len參數(shù),此參數(shù)是列表的長度,用來判斷是顯示‘暫無數(shù)據(jù)’還是列表數(shù)據(jù)以加載完全部。
fail方法返回失敗布局樣式,nodata方法返回暫無數(shù)據(jù)布局樣式。