import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import 'package:ftrecruiter/comm/utils/dark_theme_util.dart'; /// 封装下拉刷新与加载更多 class MyRefreshListView extends StatefulWidget { const MyRefreshListView({ Key? key, required this.itemCount, required this.itemBuilder, this.onRefresh, this.loadMore, this.hasMore = false, this.pageSize = 10, this.padding, this.itemExtent, }) : super(key: key); final RefreshCallback? onRefresh; final LoadMoreCallback? loadMore; final int itemCount; final bool hasMore; final IndexedWidgetBuilder itemBuilder; /// 一页的数量,默认为10 final int pageSize; /// padding属性使用时注意会破坏原有的SafeArea,需要自行计算bottom大小 final EdgeInsetsGeometry? padding; final double? itemExtent; @override _MyRefreshListViewState createState() => _MyRefreshListViewState(); } typedef RefreshCallback = Future Function(); typedef LoadMoreCallback = Future Function(); class _MyRefreshListViewState extends State { /// 是否正在加载数据 bool _isLoading = false; @override Widget build(BuildContext context) { //刷新布局包裹-系统的刷新布局 final Widget child = widget.onRefresh == null ? ListView.builder( itemCount: widget.loadMore == null ? widget.itemCount : widget.itemCount + 1, padding: widget.padding, itemExtent: widget.itemExtent, itemBuilder: (BuildContext context, int index) { /// 不需要加载更多则不需要添加FootView if (widget.loadMore == null) { return widget.itemBuilder(context, index); } else { return index < widget.itemCount ? widget.itemBuilder(context, index) : MoreWidget(widget.itemCount, widget.hasMore, widget.pageSize); } }, ) : RefreshIndicator( onRefresh: widget.onRefresh!, child: widget.itemCount == 0 ? const SizedBox() : ListView.builder( itemCount: widget.loadMore == null ? widget.itemCount : widget.itemCount + 1, padding: widget.padding, itemExtent: widget.itemExtent, itemBuilder: (BuildContext context, int index) { /// 不需要加载更多则不需要添加FootView if (widget.loadMore == null) { return widget.itemBuilder(context, index); } else { return index < widget.itemCount ? widget.itemBuilder(context, index) : MoreWidget(widget.itemCount, widget.hasMore, widget.pageSize); } }, ), ); //返回真正的布局-监听LoadMore return SafeArea( child: NotificationListener( onNotification: (ScrollNotification note) { /// 确保是垂直方向滚动,且滑动至底部 if (note.metrics.pixels == note.metrics.maxScrollExtent && note.metrics.axis == Axis.vertical) { _loadMore(); } return true; }, child: child, ), ); } Future _loadMore() async { if (widget.loadMore == null) { return; } if (_isLoading) { return; } if (!widget.hasMore) { return; } _isLoading = true; await widget.loadMore?.call(); _isLoading = false; } } //LoadMore-底部加载更多的布局 class MoreWidget extends StatelessWidget { const MoreWidget(this.itemCount, this.hasMore, this.pageSize, {Key? key}) : super(key: key); final int itemCount; final bool hasMore; final int pageSize; @override Widget build(BuildContext context) { return Container( height: 50, alignment:Alignment.center , child: Row( mainAxisAlignment: MainAxisAlignment.center, children: [ if (hasMore) const CupertinoActivityIndicator(), if (hasMore) const SizedBox( width: 5, ), // 只有一页的时候,就不显示FooterView了 Text(hasMore ? '正在加载中...' : (itemCount < pageSize ? '' : '没有了呦~'), style: TextStyle( fontSize: 14, color: DarkThemeUtil.multiColors(const Color(0x8A000000), darkColor: Colors.white54))), ], ), ); } }