import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import 'package:liftmanager/res/resources.dart'; import 'package:liftmanager/utils/theme_utils.dart'; import 'package:liftmanager/widgets/state_layout.dart'; /// 封装下拉刷新与加载更多 class MyListView extends StatefulWidget { const MyListView({ Key key, @required this.itemCount, @required this.itemBuilder, @required this.onRefresh, this.loadMore, this.normal: true, this.hasMore: false, this.stateType: StateType.empty, this.pageSize: 10, this.padding, this.itemExtent, this.showSeparator = true, }) : super(key: key); final RefreshCallback onRefresh; final LoadMoreCallback loadMore; final int itemCount; final bool hasMore; final bool normal; final IndexedWidgetBuilder itemBuilder; final StateType stateType; /// 一页的数量,默认为10 final int pageSize; final EdgeInsetsGeometry padding; final double itemExtent; final bool showSeparator; @override _MyListViewState createState() => _MyListViewState(); } typedef RefreshCallback = Future Function(); typedef LoadMoreCallback = Future Function(); class _MyListViewState extends State { /// 是否正在加载数据 bool _isLoading = false; @override Widget build(BuildContext context) { return SafeArea( child: NotificationListener( onNotification: (ScrollNotification note) { /// 确保是垂直方向滚动,且滑动至底部 if (note.metrics.pixels == note.metrics.maxScrollExtent && note.metrics.axis == Axis.vertical) { _loadMore(); } return true; }, child: RefreshIndicator( onRefresh: widget.onRefresh, child: widget.itemCount == 0 ? (widget.normal ? StateLayout(type: widget.stateType) : Container( child: null, )) : ListView.separated( shrinkWrap: true, itemCount: widget.loadMore == null ? widget.itemCount : widget.itemCount + 1, padding: widget.padding, // itemExtent: widget.itemExtent, separatorBuilder: (context, index) => widget.showSeparator ? Divider( height: 0.5, thickness: .5, ) : Container(), 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); } })), ), ); } Future _loadMore() async { if (widget.loadMore == null) { return; } if (_isLoading) { return; } if (!widget.hasMore) { return; } _isLoading = true; await widget.loadMore(); _isLoading = false; } } class MoreWidget extends StatelessWidget { const MoreWidget(this.itemCount, this.hasMore, this.pageSize); final int itemCount; final bool hasMore; final int pageSize; @override Widget build(BuildContext context) { final style = const TextStyle(color: Color(0xff666666)); return Container( color: Colors.transparent, child: Padding( padding: EdgeInsets.symmetric(vertical: 10), child: Row( mainAxisAlignment: MainAxisAlignment.center, crossAxisAlignment: CrossAxisAlignment.center, children: [ hasMore ? const CupertinoActivityIndicator() : Gaps.empty, hasMore ? Gaps.hGap5 : Gaps.empty, /// 只有一页的时候,就不显示FooterView了 Text(hasMore ? '正在加载中...' : (itemCount < pageSize ? '' : '没有了呦~'), style: style), ], ), ), ); } }