my_refresh_list.dart
3.57 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:one_poem/res/resources.dart';
import 'package:one_poem/util/theme_utils.dart';
import 'package:one_poem/widgets/state_layout.dart';
/// 封装下拉刷新与加载更多
class DeerListView extends StatefulWidget {
const DeerListView({
Key? key,
required this.itemCount,
required this.itemBuilder,
required this.onRefresh,
this.loadMore,
this.hasMore = false,
this.stateType = StateType.empty,
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;
final StateType stateType;
/// 一页的数量,默认为10
final int pageSize;
/// padding属性使用时注意会破坏原有的SafeArea,需要自行计算bottom大小
final EdgeInsetsGeometry? padding;
final double? itemExtent;
@override
_DeerListViewState 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.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);
}
},
),
);
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, this.pageSize, {Key? key}): super(key: key);
final int itemCount;
final bool hasMore;
final int pageSize;
@override
Widget build(BuildContext context) {
final TextStyle style = context.isDark ? TextStyles.textGray14 : 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(),
if (hasMore) Gaps.hGap5,
/// 只有一页的时候,就不显示FooterView了
Text(hasMore ? '正在加载中...' : (itemCount < pageSize ? '' : '没有了呦~'), style: style),
],
),
);
}
}