| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116 |
- import 'package:flutter/cupertino.dart';
- import 'package:flutter/material.dart';
- /// 封装下拉刷新与加载更多
- class DeerListView extends StatefulWidget {
- const DeerListView({
- super.key,
- required this.itemCount,
- required this.itemBuilder,
- required this.onRefresh,
- this.loadMore,
- this.hasMore = false,
- this.padding,
- this.controller,
- });
- final RefreshCallback onRefresh;
- final LoadMoreCallback? loadMore;
- final int itemCount;
- final bool hasMore;
- final IndexedWidgetBuilder itemBuilder;
- final ScrollController? controller;
- /// padding属性使用时注意会破坏原有的SafeArea,需要自行计算bottom大小
- final EdgeInsetsGeometry? padding;
- @override
- State<StatefulWidget> createState() => _DeerListViewState();
- }
- typedef RefreshCallback = Future<void> Function();
- typedef LoadMoreCallback = Future<void> Function();
- class _DeerListViewState extends State<DeerListView> {
- /// 是否正在加载数据
- bool _isLoading = false;
- @override
- Widget build(BuildContext context) {
- final Widget child = RefreshIndicator(
- onRefresh: widget.onRefresh,
- child:
- // widget.itemCount == 0 ?
- // StateLayout(type: widget.stateType) :
- ListView.separated(
- controller: widget.controller,
- itemCount:
- widget.loadMore == null ? widget.itemCount : widget.itemCount + 1,
- padding: widget.padding,
- 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);
- }
- },
- separatorBuilder: (context, index) {
- return const Divider();
- },
- ),
- );
- return SafeArea(
- child: NotificationListener<ScrollNotification>(
- onNotification: (ScrollNotification note) {
- /// 确保是垂直方向滚动,且滑动至底部
- if (note.metrics.pixels == note.metrics.maxScrollExtent &&
- note.metrics.axis == Axis.vertical) {
- _loadMore();
- }
- return true;
- },
- child: child,
- ),
- );
- }
- Future<void> _loadMore() async {
- if (widget.loadMore == null) {
- return;
- }
- if (_isLoading) {
- return;
- }
- if (!widget.hasMore) {
- return;
- }
- _isLoading = true;
- await widget.loadMore?.call();
- _isLoading = false;
- }
- }
- class MoreWidget extends StatelessWidget {
- const MoreWidget(this.itemCount, this.hasMore, {super.key});
- final int itemCount;
- final bool hasMore;
- @override
- Widget build(BuildContext context) {
- TextStyle style = const TextStyle(color: Color(0x8A000000));
- return Padding(
- padding: const EdgeInsets.symmetric(vertical: 10.0),
- child: Row(
- mainAxisAlignment: MainAxisAlignment.center,
- children: <Widget>[
- if (hasMore) const CupertinoActivityIndicator(),
- Text(hasMore ? '正在加载中...' : '没有了呦~', style: style),
- ],
- ),
- );
- }
- }
|