flutter上拉加载更多下拉刷新通用widget,child可
2020-09-21 本文已影响0人
huisedediao
1,通用性,child可以是任何widget
2,支持多种状态:
上拉加载更多:继续上拉加载更多、松手开始加载、正在加载、加载到了新数据、没有新数据
下拉刷新:继续下拉刷新、松手开始刷新、正在刷新、刷新完成
3,支持自定义每种状态的widget
源码:
效果:

思路:
下拉和上拉类似的,这里就说上拉。
借住Stack,底层是Column,上层是外部传入的child。

流程图(仅上拉):

demo:
下载源码后,跳转到下图指向的page查看效果。

class _XBRefreshDemoState extends State<XBRefreshDemo> {
ScrollController _controller = ScrollController();
GlobalKey<XBRefreshState> _refreshKey = GlobalKey();
int _itemCount = 10;
@override
void initState() {
// TODO: implement initState
super.initState();
_controller.addListener(() {
_refreshKey.currentState.receiveOffset(
_controller.offset, _controller.position.maxScrollExtent);
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("xb refresh demo"),
),
body: XBRefresh(
key: _refreshKey,
needLoadMore: true,
needRefresh: true,
///开始加载更多的回调
onBeginLoadMore: () {
Future.delayed(Duration(seconds: 2), () {
bool hasMore = false;
if (_itemCount < 20) {
hasMore = true;
setState(() {
_itemCount += 5;
});
}
///结束加载更多,传是否有新数据
_refreshKey.currentState.endLoadMore(hasMore);
});
},
onBeginRefresh: () {
Future.delayed(Duration(seconds: 1), () {
setState(() {
_itemCount = 10;
});
_refreshKey.currentState.endRefresh();
});
},
child: CustomScrollView(
controller: _controller,
physics: AlwaysScrollableScrollPhysics(
parent: BouncingScrollPhysics()),
slivers: <Widget>[
SliverList(
delegate: SliverChildBuilderDelegate((ctx, index) {
return Cell("$index", () {});
}, childCount: _itemCount))
],
)));
}
@override
void dispose() {
_controller.dispose();
super.dispose();
}
}