383462ef
吴启风
feat: 新增视频专区列表与播放功能
|
1
2
|
import 'package:cached_network_image/cached_network_image.dart';
import 'package:flutter/material.dart';
|
383462ef
吴启风
feat: 新增视频专区列表与播放功能
|
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
|
import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'package:wow_english/common/dialogs/show_dialog.dart';
import 'package:wow_english/common/request/dao/video_dao.dart';
import 'package:wow_english/common/widgets/we_app_bar.dart';
import 'package:wow_english/route/route.dart';
import 'video_zone_item.dart';
class VideoZonePage extends StatefulWidget {
const VideoZonePage({super.key});
@override
State<VideoZonePage> createState() => _VideoZonePageState();
}
class _VideoZonePageState extends State<VideoZonePage> {
late Future<List<VideoZoneItem>> _itemsFuture;
@override
void initState() {
super.initState();
|
383462ef
吴启风
feat: 新增视频专区列表与播放功能
|
24
25
26
|
_itemsFuture = VideoDao.list();
}
|
383462ef
吴启风
feat: 新增视频专区列表与播放功能
|
27
|
void _reload() {
|
9475aa49
吴启风
feat: 优化视频专区列表布局与...
|
28
29
30
|
setState(() {
_itemsFuture = VideoDao.list();
});
|
383462ef
吴启风
feat: 新增视频专区列表与播放功能
|
31
32
33
34
|
}
@override
Widget build(BuildContext context) {
|
5bc84eff
吴启风
Revert "feat: 优化视...
|
35
|
return Scaffold(
|
9475aa49
吴启风
feat: 优化视频专区列表布局与...
|
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
|
backgroundColor: Colors.white,
appBar: const WEAppBar(
titleText: '视频专区',
centerTitle: false,
),
body: FutureBuilder<List<VideoZoneItem>>(
future: _itemsFuture,
builder: (context, snapshot) {
if (snapshot.connectionState == ConnectionState.waiting) {
return const Center(child: CircularProgressIndicator());
}
if (snapshot.hasError) {
return _VideoLoadError(onRetry: _reload);
}
final items = snapshot.data ?? const <VideoZoneItem>[];
if (items.isEmpty) {
return const Center(
child: Text(
'暂无视频',
style: TextStyle(color: Color(0xFF999999), fontSize: 18),
),
);
}
return RefreshIndicator(
onRefresh: () async {
final future = VideoDao.list();
setState(() => _itemsFuture = future);
await future;
},
child: LayoutBuilder(
builder: (context, constraints) {
|
54f62f82
吴启风
fix: 自适应视频标题高度避免文字裁切
|
67
|
final titleStyle = _VideoCard.createTitleStyle(context);
|
9475aa49
吴启风
feat: 优化视频专区列表布局与...
|
68
69
70
|
return GridView.builder(
physics: const AlwaysScrollableScrollPhysics(),
padding: EdgeInsets.fromLTRB(
|
5bc84eff
吴启风
Revert "feat: 优化视...
|
71
|
14.w,
|
9475aa49
吴启风
feat: 优化视频专区列表布局与...
|
72
|
10.h,
|
5bc84eff
吴启风
Revert "feat: 优化视...
|
73
|
14.w,
|
9475aa49
吴启风
feat: 优化视频专区列表布局与...
|
74
75
76
|
16.h,
),
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
|
5bc84eff
吴启风
Revert "feat: 优化视...
|
77
|
crossAxisCount: 4,
|
9475aa49
吴启风
feat: 优化视频专区列表布局与...
|
78
|
mainAxisSpacing: 14.h,
|
5bc84eff
吴启风
Revert "feat: 优化视...
|
79
80
|
crossAxisSpacing: 12.w,
childAspectRatio: 1.55,
|
9475aa49
吴启风
feat: 优化视频专区列表布局与...
|
81
82
83
84
85
|
),
itemCount: items.length,
itemBuilder: (context, index) => _VideoCard(
item: items[index],
onTap: () => _openVideo(items, index),
|
54f62f82
吴启风
fix: 自适应视频标题高度避免文字裁切
|
86
|
titleStyle: titleStyle,
|
9475aa49
吴启风
feat: 优化视频专区列表布局与...
|
87
88
89
|
),
);
},
|
383462ef
吴启风
feat: 新增视频专区列表与播放功能
|
90
91
|
),
);
|
9475aa49
吴启风
feat: 优化视频专区列表布局与...
|
92
93
|
},
),
|
5bc84eff
吴启风
Revert "feat: 优化视...
|
94
|
);
|
383462ef
吴启风
feat: 新增视频专区列表与播放功能
|
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
|
}
void _openVideo(List<VideoZoneItem> items, int index) {
final item = items[index];
if (!item.accessible || item.videoUrl.isEmpty) {
showTwoActionDialog('提示', '取消', '去购买', '购买课程后即可观看视频。', leftTap: popPage,
rightTap: () {
popPage();
pushNamed(AppRouteName.shop);
});
return;
}
Navigator.of(context).pushNamed(
AppRouteName.videoZonePlayer,
arguments: {
'items': items
.where((video) => video.accessible && video.videoUrl.isNotEmpty)
.toList(),
'initialVideoId': item.id,
},
|
5bc84eff
吴启风
Revert "feat: 优化视...
|
115
|
).then((_) => _reload());
|
383462ef
吴启风
feat: 新增视频专区列表与播放功能
|
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
|
}
}
class _VideoLoadError extends StatelessWidget {
const _VideoLoadError({required this.onRetry});
final VoidCallback onRetry;
@override
Widget build(BuildContext context) {
return Center(
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
const Text(
'视频加载失败,请稍后重试',
style: TextStyle(color: Color(0xFF999999), fontSize: 18),
),
const SizedBox(height: 12),
FilledButton(onPressed: onRetry, child: const Text('重新加载')),
],
),
);
}
}
class _VideoCard extends StatelessWidget {
|
54f62f82
吴启风
fix: 自适应视频标题高度避免文字裁切
|
143
144
145
146
147
|
const _VideoCard({
required this.item,
required this.onTap,
required this.titleStyle,
});
|
383462ef
吴启风
feat: 新增视频专区列表与播放功能
|
148
149
150
|
final VideoZoneItem item;
final VoidCallback onTap;
|
54f62f82
吴启风
fix: 自适应视频标题高度避免文字裁切
|
151
152
153
154
155
156
157
158
|
final TextStyle titleStyle;
static TextStyle createTitleStyle(BuildContext context) => TextStyle(
color: const Color(0xFF222222),
fontFamily: null,
fontSize: 17.sp,
fontWeight: FontWeight.w500,
);
|
383462ef
吴启风
feat: 新增视频专区列表与播放功能
|
159
160
161
162
|
@override
Widget build(BuildContext context) {
return InkWell(
|
c67962ab
吴启风
feat: 视频卡片点击区域和封面...
|
163
|
borderRadius: BorderRadius.circular(12.r),
|
383462ef
吴启风
feat: 新增视频专区列表与播放功能
|
164
165
166
167
|
onTap: onTap,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
|
5bc84eff
吴启风
Revert "feat: 优化视...
|
168
|
Expanded(
|
383462ef
吴启风
feat: 新增视频专区列表与播放功能
|
169
|
child: ClipRRect(
|
c67962ab
吴启风
feat: 视频卡片点击区域和封面...
|
170
|
borderRadius: BorderRadius.circular(12.r),
|
9475aa49
吴启风
feat: 优化视频专区列表布局与...
|
171
172
173
174
175
176
177
178
179
180
181
182
|
child: CachedNetworkImage(
imageUrl: item.coverUrl,
fit: BoxFit.cover,
placeholder: (_, __) => const ColoredBox(
color: Color(0xFFF2F2F2),
child: Center(child: CircularProgressIndicator()),
),
errorWidget: (_, __, ___) => const ColoredBox(
color: Color(0xFFF2F2F2),
child: Icon(Icons.broken_image_outlined,
color: Color(0xFFAAAAAA)),
),
|
383462ef
吴启风
feat: 新增视频专区列表与播放功能
|
183
184
185
186
|
),
),
),
SizedBox(height: 5.h),
|
54f62f82
吴启风
fix: 自适应视频标题高度避免文字裁切
|
187
188
189
190
191
|
Text(
item.title,
maxLines: 1,
overflow: TextOverflow.ellipsis,
style: titleStyle,
|
383462ef
吴启风
feat: 新增视频专区列表与播放功能
|
192
193
194
195
196
197
|
),
],
),
);
}
}
|