video_list_page.dart
3.84 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
123
124
125
126
127
import 'package:flutter/material.dart';
import 'package:one_poem/order/provider/order_page_provider.dart';
import 'package:one_poem/order/widgets/order_item.dart';
import 'package:one_poem/order/widgets/order_tag_item.dart';
import 'package:one_poem/util/change_notifier_manage.dart';
import 'package:one_poem/widgets/my_refresh_list.dart';
import 'package:one_poem/widgets/state_layout.dart';
import 'package:provider/provider.dart';
class VideoListPage extends StatefulWidget {
const VideoListPage({
Key? key,
required this.index,
}): super(key: key);
final int index;
@override
_VideoListPageState createState() => _VideoListPageState();
}
class _VideoListPageState extends State<VideoListPage> with AutomaticKeepAliveClientMixin<VideoListPage>, ChangeNotifierMixin<VideoListPage>{
final ScrollController _controller = ScrollController();
final StateType _stateType = StateType.loading;
/// 是否正在加载数据
bool _isLoading = false;
final int _maxPage = 3;
int _page = 1;
int _index = 0;
List<String> _list = <String>[];
@override
void initState() {
super.initState();
_index = widget.index;
_onRefresh();
}
@override
Map<ChangeNotifier, List<VoidCallback>?>? changeNotifier() {
return {_controller: null};
}
@override
Widget build(BuildContext context) {
super.build(context);
return NotificationListener(
onNotification: (ScrollNotification note) {
if (note.metrics.pixels == note.metrics.maxScrollExtent) {
_loadMore();
}
return true;
},
child: RefreshIndicator(
onRefresh: _onRefresh,
displacement: 120.0, /// 默认40, 多添加的80为Header高度
child: Consumer<OrderPageProvider>(
builder: (_, provider, child) {
return CustomScrollView(
/// 这里指定controller可以与外层NestedScrollView的滚动分离,避免一处滑动,5个Tab中的列表同步滑动。
/// 这种方法的缺点是会重新layout列表
controller: _index != provider.index ? _controller : null,
key: PageStorageKey<String>('$_index'),
slivers: <Widget>[
SliverOverlapInjector(
///SliverAppBar的expandedHeight高度,避免重叠
handle: NestedScrollView.sliverOverlapAbsorberHandleFor(context),
),
child!,
],
);
},
child: SliverPadding(
padding: const EdgeInsets.symmetric(horizontal: 16.0),
sliver: _list.isEmpty ? SliverFillRemaining(child: StateLayout(type: _stateType)) :
SliverList(
delegate: SliverChildBuilderDelegate((BuildContext context, int index) {
return index < _list.length ?
(index % 5 == 0 ?
const OrderTagItem(date: '2021年2月5日', orderTotal: 4) :
OrderItem(key: Key('order_item_$index'), index: index, tabIndex: _index,)
) :
MoreWidget(_list.length, _hasMore(), 10);
},
childCount: _list.length + 1),
),
),
),
),
);
}
Future<void> _onRefresh() async {
await Future.delayed(const Duration(seconds: 2), () {
setState(() {
_page = 1;
_list = List.generate(10, (i) => 'newItem:$i');
});
});
}
bool _hasMore() {
return _page < _maxPage;
}
Future<void> _loadMore() async {
if (_isLoading) {
return;
}
if (!_hasMore()) {
return;
}
_isLoading = true;
await Future.delayed(const Duration(seconds: 2), () {
setState(() {
_list.addAll(List.generate(10, (i) => 'newItem:$i'));
_page ++;
_isLoading = false;
});
});
}
@override
bool get wantKeepAlive => true;
}