使用到的插件
pull_to_refresh | Flutter Packagea widget provided to the flutter scroll component drop-down refresh and pull up load.https://pub.flutter-io.cn/packages/pull_to_refresh
#下拉刷新
pull_to_refresh: ^2.0.0
大致效果:
在这里我们对? pull_to_refresh 进行了两次封装;两次的目的不一样
- 第一个是为了防止 插件不维护 或者更换使用其他插件 的时候避免 多个页面都要修改,这个时候 给第三方插件 外边包裹一层是一个 很好的选择:文件名: app_pull_refresh.dart,必要的时候只修改这一个文件就可以
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:pull_to_refresh/pull_to_refresh.dart';
class AppPullRefresh extends StatelessWidget {
final Widget child;
final VoidCallback? onRefresh;
final VoidCallback? onLoading;
final bool initialRefresh;
const AppPullRefresh(
{Key? key,
required this.child,
this.onRefresh,
this.onLoading,
this.initialRefresh = false})
: super(key: key);
@override
Widget build(BuildContext context) {
return RefreshConfiguration(
footerTriggerDistance: 15,
dragSpeedRatio: 0.91,
headerBuilder: () => ClassicHeader(),
footerBuilder: () => ClassicFooter(),
enableLoadingWhenNoData: false,
enableRefreshVibrate: false,
enableLoadMoreVibrate: false,
shouldFooterFollowWhenNotFull: (state) {
// If you want load more with noMoreData state ,may be you should return false
return false;
},
child: child);
}
}
class AppSmartRefresher extends StatelessWidget {
final Widget child;
final RefreshController controller;
final VoidCallback? onRefresh;
final VoidCallback? onLoading;
const AppSmartRefresher({
Key? key,
required this.child,
required this.controller,
this.onRefresh,
this.onLoading,
}) : super(key: key);
@override
Widget build(BuildContext context) {
return SmartRefresher(
enablePullDown: true,
enablePullUp: true,
// header: WaterDropHeader(),
header: const ClassicHeader(),
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: controller,
onRefresh: onRefresh,
onLoading: onLoading,
child: child,
);
}
}
- 第二次是为了简化使用 文件名:abstract_app_page_refresh.dart
import 'package:bilibili/widget/app_pull_refresh.dart';
import 'package:flutter/material.dart';
import 'package:pull_to_refresh/pull_to_refresh.dart';
///M 为 驱动页面页面要展示的 数据类型 泛型 W 则是要展示的页面 约束自 StatefullWidget
abstract class AbstractAppPageRefresh<M, W extends StatefulWidget>
extends State<W> with AutomaticKeepAliveClientMixin {
List<M> dataList = [];
int pageIndex = 1;
final RefreshController refreshController =
RefreshController(initialRefresh: false);
onRefresh();//下拉刷新
onLoading();//上拉加载更多
buildView();//根据数据展示 列表类容;这几放在了继承类中实现 灵活性更强
@override
void initState() {
// TODO: implement initState
super.initState();
onRefresh();
}
@override
Widget build(BuildContext context) {
return Container(
child: AppSmartRefresher(
controller: refreshController,
onRefresh: onRefresh,
onLoading: onLoading,
child: buildView(),
),
);
}
@override
void dispose() {
// TODO: implement dispose
super.dispose();
refreshController.dispose();
}
}
?
具体在页面中的使用:
内部页面: page_favorite_content.dart
import 'package:bilibili/widget/abstract_app_page_refresh.dart';
import 'package:bilibili/http/dao/dao_favorrite.dart';
import 'package:bilibili/model/ranking_mo.dart';
import 'package:bilibili/model/video_model.dart';
import 'package:bilibili/util/toast.dart';
import 'package:bilibili/widget/loading_widget.dart';
import 'package:bilibili/widget/video_large_card.dart';
import 'package:flutter/material.dart';
class PageFavoriteContent extends StatefulWidget {
const PageFavoriteContent({Key? key}) : super(key: key);
@override
_PageFavoriteContentState createState() => _PageFavoriteContentState();
}
///重点在这里
///重点在这里
///重点在这里
///重点在这里
///重点在这里
///重点在这里 以前是 继承 State 这里换成我们的 AbstractAppPageRefresh
class _PageFavoriteContentState
extends AbstractAppPageRefresh<VideoModel, PageFavoriteContent> {
@override
// TODO: implement wantKeepAlive
bool get wantKeepAlive => false;
@override
buildView() {
return dataList.length == 0
? const Center(
child: LoadingWidget(),// 等待数据的进度条
)
: ListView.builder(//具体要展示的别表类容
padding: EdgeInsets.only(top: 10),
// itemExtent: 10,
addAutomaticKeepAlives: false,
itemCount: dataList.length,
itemBuilder: (BuildContext content, int index) {
return VideoLargeCard(videoModel: dataList[index]);
},
);
}
@override
onLoading() async {
int pageStep = pageIndex + 1;
int pageSize = 50;
try {
/// 数据的请求
RankingMo result = await DaoFavorite.favoriteList(
pageIndex: pageIndex, pageSize: pageSize);
if (result.list.length < pageSize) {///没有更多 类容
refreshController.loadNoData();
}
setState(() {
if (result.list.isNotEmpty) {
dataList = [...dataList, ...result.list];//数据合并
pageIndex = pageStep;
}
});
} catch (ex) {
print("_loadData 异常--->$ex");
showToastWarn(ex.toString());
}
refreshController.loadComplete();
}
@override
onRefresh() async {
// TODO: implement onRefresh
int pageSize = 50;
try {
pageIndex = 1;
/// 数据的请求
RankingMo result = await DaoFavorite.favoriteList(
pageIndex: pageIndex, pageSize: pageSize);
if (result.list.length < pageSize) {///没有更多 类容
refreshController.loadNoData();
}
setState(() {
dataList = result.list;
});
} catch (ex) {
print("_loadData 异常--->$ex");
showToastWarn(ex.toString());
}
refreshController.refreshCompleted();
}
}
外部页面:page_favorite.dart
import 'package:bilibili/pages/page_favorite_content.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
class PageFavorite extends StatelessWidget {
const PageFavorite({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
// TODO: implement build
return Scaffold(
appBar: AppBar(
centerTitle: true,
title: const Text(
"收藏",
style: TextStyle(fontSize: 14),
),
),
body: const PageFavoriteContent(),//要展示具下拉刷新 上拉加载更多的页面
);
}
}
|