Commit 993c1a046153fdc4ff0eca8a9188456b17ac25a4
1 parent
13e6d11d
feat:添加数据模型
Showing
20 changed files
with
341 additions
and
74 deletions
lib/common/request/apis.dart
... | ... | @@ -22,4 +22,24 @@ class Apis { |
22 | 22 | // GET /home/courseLesson |
23 | 23 | // 接口地址:https://app.apifox.com/link/project/2684751/apis/api-89897662 |
24 | 24 | static const String courseLesson = 'home/courseLesson'; |
25 | + | |
26 | + /// 磨耳朵 | |
27 | + /// GET | |
28 | + static const String ears = '/course/grinding/ears'; | |
29 | + | |
30 | + /// 视频跟读 | |
31 | + /// GET | |
32 | + static const String followRead = '/course/video/follow/read'; | |
33 | + | |
34 | + /// 视频跟读内容 | |
35 | + /// GET | |
36 | + static const String readContent = '/course/video/follow/read/content'; | |
37 | + | |
38 | + /// 视频跟读提交结果 | |
39 | + /// POST | |
40 | + static const String followResult = '/course/submit/follow/result'; | |
41 | + | |
42 | + /// 获取课程内容 | |
43 | + /// GET | |
44 | + static const String process = '/course/process'; | |
25 | 45 | } | ... | ... |
lib/common/request/dao/home_dao.dart
... | ... | @@ -3,14 +3,14 @@ import 'package:wow_english/common/request/request_client.dart'; |
3 | 3 | |
4 | 4 | class HomeDao { |
5 | 5 | ///获取课程模块信息 |
6 | - static Future courseModule() async { | |
7 | - var data = requestClient.get(Apis.courseModule); | |
6 | + static Future<List<dynamic>?> courseModule() async { | |
7 | + var data = await requestClient.get<List<dynamic>?>(Apis.courseModule); | |
8 | 8 | return data; |
9 | 9 | } |
10 | 10 | |
11 | 11 | ///课程列表 |
12 | 12 | static Future courseLesson() async { |
13 | - var data = requestClient.get(Apis.courseLesson); | |
13 | + var data = await requestClient.get(Apis.courseLesson); | |
14 | 14 | return data; |
15 | 15 | } |
16 | 16 | } | ... | ... |
lib/common/request/dao/listen_dao.dart
0 → 100644
1 | +import 'package:wow_english/common/request/apis.dart'; | |
2 | +import 'package:wow_english/common/request/request_client.dart'; | |
3 | + | |
4 | +class ListenDao { | |
5 | + /// 磨耳朵 | |
6 | + static Future listen() async { | |
7 | + var data = await requestClient.get(Apis.ears); | |
8 | + return data; | |
9 | + } | |
10 | +} | |
0 | 11 | \ No newline at end of file | ... | ... |
lib/generated/json/base/json_convert_content.dart
... | ... | @@ -4,6 +4,8 @@ |
4 | 4 | |
5 | 5 | // This file is automatically generated. DO NOT EDIT, all your changes would be lost. |
6 | 6 | import 'package:flutter/material.dart' show debugPrint; |
7 | +import 'package:wow_english/models/lesson_entity.dart'; | |
8 | +import 'package:wow_english/models/listen_entity.dart'; | |
7 | 9 | import 'package:wow_english/models/user_entity.dart'; |
8 | 10 | |
9 | 11 | JsonConvert jsonConvert = JsonConvert(); |
... | ... | @@ -12,6 +14,8 @@ typedef EnumConvertFunction<T> = T Function(String value); |
12 | 14 | |
13 | 15 | class JsonConvert { |
14 | 16 | static final Map<String, JsonConvertFunction> convertFuncMap = { |
17 | + (LessonEntity).toString(): LessonEntity.fromJson, | |
18 | + (ListenEntity).toString(): ListenEntity.fromJson, | |
15 | 19 | (UserEntity).toString(): UserEntity.fromJson, |
16 | 20 | }; |
17 | 21 | |
... | ... | @@ -91,12 +95,18 @@ List<T>? convertListNotNull<T>(dynamic value, {EnumConvertFunction? enumConvert} |
91 | 95 | |
92 | 96 | //list is returned by type |
93 | 97 | static M? _getListChildType<M>(List<Map<String, dynamic>> data) { |
98 | + if(<LessonEntity>[] is M){ | |
99 | + return data.map<LessonEntity>((Map<String, dynamic> e) => LessonEntity.fromJson(e)).toList() as M; | |
100 | + } | |
101 | + if(<ListenEntity>[] is M){ | |
102 | + return data.map<ListenEntity>((Map<String, dynamic> e) => ListenEntity.fromJson(e)).toList() as M; | |
103 | + } | |
94 | 104 | if(<UserEntity>[] is M){ |
95 | 105 | return data.map<UserEntity>((Map<String, dynamic> e) => UserEntity.fromJson(e)).toList() as M; |
96 | 106 | } |
97 | 107 | |
98 | 108 | debugPrint("${M.toString()} not found"); |
99 | - | |
109 | + | |
100 | 110 | return null; |
101 | 111 | } |
102 | 112 | |
... | ... | @@ -107,4 +117,4 @@ List<T>? convertListNotNull<T>(dynamic value, {EnumConvertFunction? enumConvert} |
107 | 117 | return jsonConvert.convert<M>(json); |
108 | 118 | } |
109 | 119 | } |
110 | 120 | -} |
121 | +} | |
111 | 122 | \ No newline at end of file | ... | ... |
lib/generated/json/base/json_field.dart
... | ... | @@ -14,12 +14,12 @@ class JSONField { |
14 | 14 | |
15 | 15 | //Whether to participate in toJson |
16 | 16 | final bool? serialize; |
17 | - | |
17 | + | |
18 | 18 | //Whether to participate in fromMap |
19 | 19 | final bool? deserialize; |
20 | - | |
20 | + | |
21 | 21 | //Enumeration or not |
22 | 22 | final bool? isEnum; |
23 | - | |
23 | + | |
24 | 24 | const JSONField({this.name, this.serialize, this.deserialize, this.isEnum}); |
25 | 25 | } | ... | ... |
lib/generated/json/lesson_entity.g.dart
0 → 100644
1 | +import 'package:wow_english/generated/json/base/json_convert_content.dart'; | |
2 | +import 'package:wow_english/models/lesson_entity.dart'; | |
3 | + | |
4 | +LessonEntity $LessonEntityFromJson(Map<String, dynamic> json) { | |
5 | + final LessonEntity lessonEntity = LessonEntity(); | |
6 | + final String? code = jsonConvert.convert<String>(json['code']); | |
7 | + if (code != null) { | |
8 | + lessonEntity.code = code; | |
9 | + } | |
10 | + final int? courseModuleThemeId = jsonConvert.convert<int>(json['courseModuleThemeId']); | |
11 | + if (courseModuleThemeId != null) { | |
12 | + lessonEntity.courseModuleThemeId = courseModuleThemeId; | |
13 | + } | |
14 | + final int? courseTotal = jsonConvert.convert<int>(json['courseTotal']); | |
15 | + if (courseTotal != null) { | |
16 | + lessonEntity.courseTotal = courseTotal; | |
17 | + } | |
18 | + final String? coverUrl = jsonConvert.convert<String>(json['coverUrl']); | |
19 | + if (coverUrl != null) { | |
20 | + lessonEntity.coverUrl = coverUrl; | |
21 | + } | |
22 | + final String? createTime = jsonConvert.convert<String>(json['createTime']); | |
23 | + if (createTime != null) { | |
24 | + lessonEntity.createTime = createTime; | |
25 | + } | |
26 | + final String? deleted = jsonConvert.convert<String>(json['deleted']); | |
27 | + if (deleted != null) { | |
28 | + lessonEntity.deleted = deleted; | |
29 | + } | |
30 | + final String? des = jsonConvert.convert<String>(json['des']); | |
31 | + if (des != null) { | |
32 | + lessonEntity.des = des; | |
33 | + } | |
34 | + final String? id = jsonConvert.convert<String>(json['id']); | |
35 | + if (id != null) { | |
36 | + lessonEntity.id = id; | |
37 | + } | |
38 | + final String? modifyTime = jsonConvert.convert<String>(json['modifyTime']); | |
39 | + if (modifyTime != null) { | |
40 | + lessonEntity.modifyTime = modifyTime; | |
41 | + } | |
42 | + final String? name = jsonConvert.convert<String>(json['name']); | |
43 | + if (name != null) { | |
44 | + lessonEntity.name = name; | |
45 | + } | |
46 | + final int? opening = jsonConvert.convert<int>(json['opening']); | |
47 | + if (opening != null) { | |
48 | + lessonEntity.opening = opening; | |
49 | + } | |
50 | + final String? picUrl = jsonConvert.convert<String>(json['picUrl']); | |
51 | + if (picUrl != null) { | |
52 | + lessonEntity.picUrl = picUrl; | |
53 | + } | |
54 | + final int? sortOrder = jsonConvert.convert<int>(json['sortOrder']); | |
55 | + if (sortOrder != null) { | |
56 | + lessonEntity.sortOrder = sortOrder; | |
57 | + } | |
58 | + final int? status = jsonConvert.convert<int>(json['status']); | |
59 | + if (status != null) { | |
60 | + lessonEntity.status = status; | |
61 | + } | |
62 | + return lessonEntity; | |
63 | +} | |
64 | + | |
65 | +Map<String, dynamic> $LessonEntityToJson(LessonEntity entity) { | |
66 | + final Map<String, dynamic> data = <String, dynamic>{}; | |
67 | + data['code'] = entity.code; | |
68 | + data['courseModuleThemeId'] = entity.courseModuleThemeId; | |
69 | + data['courseTotal'] = entity.courseTotal; | |
70 | + data['coverUrl'] = entity.coverUrl; | |
71 | + data['createTime'] = entity.createTime; | |
72 | + data['deleted'] = entity.deleted; | |
73 | + data['des'] = entity.des; | |
74 | + data['id'] = entity.id; | |
75 | + data['modifyTime'] = entity.modifyTime; | |
76 | + data['name'] = entity.name; | |
77 | + data['opening'] = entity.opening; | |
78 | + data['picUrl'] = entity.picUrl; | |
79 | + data['sortOrder'] = entity.sortOrder; | |
80 | + data['status'] = entity.status; | |
81 | + return data; | |
82 | +} | |
0 | 83 | \ No newline at end of file | ... | ... |
lib/generated/json/listen_entity.g.dart
0 → 100644
1 | +import 'package:wow_english/generated/json/base/json_convert_content.dart'; | |
2 | +import 'package:wow_english/models/listen_entity.dart'; | |
3 | + | |
4 | +ListenEntity $ListenEntityFromJson(Map<String, dynamic> json) { | |
5 | + final ListenEntity listenEntity = ListenEntity(); | |
6 | + final String? coverUrl = jsonConvert.convert<String>(json['coverUrl']); | |
7 | + if (coverUrl != null) { | |
8 | + listenEntity.coverUrl = coverUrl; | |
9 | + } | |
10 | + final String? createTime = jsonConvert.convert<String>(json['createTime']); | |
11 | + if (createTime != null) { | |
12 | + listenEntity.createTime = createTime; | |
13 | + } | |
14 | + final String? deleted = jsonConvert.convert<String>(json['deleted']); | |
15 | + if (deleted != null) { | |
16 | + listenEntity.deleted = deleted; | |
17 | + } | |
18 | + final String? id = jsonConvert.convert<String>(json['id']); | |
19 | + if (id != null) { | |
20 | + listenEntity.id = id; | |
21 | + } | |
22 | + final bool? lock = jsonConvert.convert<bool>(json['lock']); | |
23 | + if (lock != null) { | |
24 | + listenEntity.lock = lock; | |
25 | + } | |
26 | + final String? modifyTime = jsonConvert.convert<String>(json['modifyTime']); | |
27 | + if (modifyTime != null) { | |
28 | + listenEntity.modifyTime = modifyTime; | |
29 | + } | |
30 | + final double? sortOrder = jsonConvert.convert<double>(json['sortOrder']); | |
31 | + if (sortOrder != null) { | |
32 | + listenEntity.sortOrder = sortOrder; | |
33 | + } | |
34 | + final double? status = jsonConvert.convert<double>(json['status']); | |
35 | + if (status != null) { | |
36 | + listenEntity.status = status; | |
37 | + } | |
38 | + final String? subtitleUrl = jsonConvert.convert<String>(json['subtitleUrl']); | |
39 | + if (subtitleUrl != null) { | |
40 | + listenEntity.subtitleUrl = subtitleUrl; | |
41 | + } | |
42 | + final String? title = jsonConvert.convert<String>(json['title']); | |
43 | + if (title != null) { | |
44 | + listenEntity.title = title; | |
45 | + } | |
46 | + final String? videoUrl = jsonConvert.convert<String>(json['videoUrl']); | |
47 | + if (videoUrl != null) { | |
48 | + listenEntity.videoUrl = videoUrl; | |
49 | + } | |
50 | + return listenEntity; | |
51 | +} | |
52 | + | |
53 | +Map<String, dynamic> $ListenEntityToJson(ListenEntity entity) { | |
54 | + final Map<String, dynamic> data = <String, dynamic>{}; | |
55 | + data['coverUrl'] = entity.coverUrl; | |
56 | + data['createTime'] = entity.createTime; | |
57 | + data['deleted'] = entity.deleted; | |
58 | + data['id'] = entity.id; | |
59 | + data['lock'] = entity.lock; | |
60 | + data['modifyTime'] = entity.modifyTime; | |
61 | + data['sortOrder'] = entity.sortOrder; | |
62 | + data['status'] = entity.status; | |
63 | + data['subtitleUrl'] = entity.subtitleUrl; | |
64 | + data['title'] = entity.title; | |
65 | + data['videoUrl'] = entity.videoUrl; | |
66 | + return data; | |
67 | +} | |
0 | 68 | \ No newline at end of file | ... | ... |
lib/generated/json/user_entity.g.dart
lib/models/lesson_entity.dart
0 → 100644
1 | +import 'package:wow_english/generated/json/base/json_field.dart'; | |
2 | +import 'package:wow_english/generated/json/lesson_entity.g.dart'; | |
3 | +import 'dart:convert'; | |
4 | + | |
5 | +@JsonSerializable() | |
6 | +class LessonEntity { | |
7 | + String? code; | |
8 | + int? courseModuleThemeId; | |
9 | + int? courseTotal; | |
10 | + String? coverUrl; | |
11 | + String? createTime; | |
12 | + String? deleted; | |
13 | + String? des; | |
14 | + String? id; | |
15 | + String? modifyTime; | |
16 | + String? name; | |
17 | + int? opening; | |
18 | + String? picUrl; | |
19 | + int? sortOrder; | |
20 | + int? status; | |
21 | + | |
22 | + LessonEntity(); | |
23 | + | |
24 | + factory LessonEntity.fromJson(Map<String, dynamic> json) => $LessonEntityFromJson(json); | |
25 | + | |
26 | + Map<String, dynamic> toJson() => $LessonEntityToJson(this); | |
27 | + | |
28 | + @override | |
29 | + String toString() { | |
30 | + return jsonEncode(this); | |
31 | + } | |
32 | +} | |
0 | 33 | \ No newline at end of file | ... | ... |
lib/models/listen_entity.dart
0 → 100644
1 | +import 'package:wow_english/generated/json/base/json_field.dart'; | |
2 | +import 'package:wow_english/generated/json/listen_entity.g.dart'; | |
3 | +import 'dart:convert'; | |
4 | + | |
5 | +@JsonSerializable() | |
6 | +class ListenEntity { | |
7 | + String? coverUrl; | |
8 | + String? createTime; | |
9 | + String? deleted; | |
10 | + String? id; | |
11 | + bool? lock; | |
12 | + String? modifyTime; | |
13 | + double? sortOrder; | |
14 | + double? status; | |
15 | + String? subtitleUrl; | |
16 | + String? title; | |
17 | + String? videoUrl; | |
18 | + | |
19 | + ListenEntity(); | |
20 | + | |
21 | + factory ListenEntity.fromJson(Map<String, dynamic> json) => $ListenEntityFromJson(json); | |
22 | + | |
23 | + Map<String, dynamic> toJson() => $ListenEntityToJson(this); | |
24 | + | |
25 | + @override | |
26 | + String toString() { | |
27 | + return jsonEncode(this); | |
28 | + } | |
29 | +} | |
0 | 30 | \ No newline at end of file | ... | ... |
lib/pages/home/bloc/home_bloc.dart
1 | 1 | import 'package:flutter/cupertino.dart'; |
2 | 2 | import 'package:flutter_bloc/flutter_bloc.dart'; |
3 | +import 'package:flutter_easyloading/flutter_easyloading.dart'; | |
3 | 4 | import 'package:wow_english/common/request/dao/home_dao.dart'; |
4 | 5 | import 'package:wow_english/common/request/exception.dart'; |
5 | 6 | import 'package:wow_english/utils/loading.dart'; |
... | ... | @@ -9,9 +10,7 @@ part 'home_state.dart'; |
9 | 10 | |
10 | 11 | class HomeBloc extends Bloc<HomeEvent, HomeState> { |
11 | 12 | HomeBloc() : super(HomeInitial()) { |
12 | - on<HomeEvent>((event, emit) { | |
13 | - // TODO: implement event handler | |
14 | - }); | |
13 | + on<RequestDataEvent>(_requestData); | |
15 | 14 | } |
16 | 15 | |
17 | 16 | Future<void> requestData() async { |
... | ... | @@ -22,8 +21,22 @@ class HomeBloc extends Bloc<HomeEvent, HomeState> { |
22 | 21 | }); |
23 | 22 | } catch (e) { |
24 | 23 | if (e is ApiException) { |
24 | + EasyLoading.showToast(e.message.toString()); | |
25 | + } | |
26 | + } | |
27 | + } | |
25 | 28 | |
29 | + void _requestData(RequestDataEvent event, Emitter<HomeState> emitter) async { | |
30 | + try { | |
31 | + await loading(() async { | |
32 | + HomeDao.courseLesson(); | |
33 | + emitter(HomeDataLoadState()); | |
34 | + }); | |
35 | + } catch (e) { | |
36 | + if (e is ApiException) { | |
37 | + EasyLoading.showToast(e.message.toString()); | |
26 | 38 | } |
27 | 39 | } |
28 | 40 | } |
29 | 41 | } |
42 | + | ... | ... |
lib/pages/home/bloc/home_event.dart
lib/pages/lessons/bloc/lesson_bloc.dart
1 | +import 'dart:convert'; | |
2 | + | |
1 | 3 | import 'package:flutter/cupertino.dart'; |
4 | +import 'package:flutter/foundation.dart'; | |
2 | 5 | import 'package:flutter_bloc/flutter_bloc.dart'; |
3 | 6 | import 'package:wow_english/common/request/dao/home_dao.dart'; |
4 | 7 | import 'package:wow_english/common/request/exception.dart'; |
8 | +import 'package:wow_english/models/lesson_entity.dart'; | |
5 | 9 | import 'package:wow_english/utils/loading.dart'; |
6 | 10 | |
7 | 11 | part 'lesson_event.dart'; |
... | ... | @@ -17,6 +21,9 @@ class LessonBloc extends Bloc<LessonEvent, LessonState> { |
17 | 21 | |
18 | 22 | int get currentPageIndex => _currentPageIndex; |
19 | 23 | |
24 | + List<LessonEntity?> _listData = []; | |
25 | + List<LessonEntity?> get listData => _listData; | |
26 | + | |
20 | 27 | LessonBloc(this.pageIndex,this.pageController) : super(LessonInitial()) { |
21 | 28 | _currentPageIndex = pageIndex; |
22 | 29 | on<PageViewChangeIndexEvent>(_pageIndexChange); |
... | ... | @@ -25,7 +32,13 @@ class LessonBloc extends Bloc<LessonEvent, LessonState> { |
25 | 32 | Future<void> requestData() async { |
26 | 33 | try { |
27 | 34 | await loading(() async { |
28 | - HomeDao.courseModule(); | |
35 | + List list = await HomeDao.courseModule()??[]; | |
36 | + // if (list.isNotEmpty) { | |
37 | + // for (dynamic jsonStr in list) { | |
38 | + // LessonEntity? data = LessonEntity.fromJson(jsonStr); | |
39 | + // _listData.add(data); | |
40 | + // } | |
41 | + // } | |
29 | 42 | emit(LessonDataLoadState()); |
30 | 43 | }); |
31 | 44 | } catch (e) { | ... | ... |
lib/pages/lessons/lesson_page.dart
... | ... | @@ -77,7 +77,7 @@ class _LessonPageView extends StatelessWidget { |
77 | 77 | SizedBox( |
78 | 78 | height: _cardHeight, |
79 | 79 | child: PageView.builder( |
80 | - itemCount: 10, | |
80 | + itemCount: bloc.listData.length, | |
81 | 81 | controller: bloc.pageController, |
82 | 82 | onPageChanged: (int index) { |
83 | 83 | bloc.add(PageViewChangeIndexEvent(index)); |
... | ... | @@ -125,14 +125,6 @@ class _LessonPageView extends StatelessWidget { |
125 | 125 | ), |
126 | 126 | ); |
127 | 127 | }), |
128 | - // child: PageView.builder( | |
129 | - // itemCount: 10, | |
130 | - // controller: bloc.pageController, | |
131 | - // onPageChanged: (int index) { | |
132 | - // bloc.add(PageViewChangeIndexEvent(index)); | |
133 | - // }, | |
134 | - // itemBuilder: (context,index) => _itemNumCard(index) | |
135 | - // ), | |
136 | 128 | ) |
137 | 129 | ], |
138 | 130 | ), |
... | ... | @@ -179,44 +171,4 @@ class _LessonPageView extends StatelessWidget { |
179 | 171 | ), |
180 | 172 | ); |
181 | 173 | }); |
182 | - | |
183 | - Widget _itemNumCard(int index) => BlocBuilder<LessonBloc,LessonState>( | |
184 | - builder: (context, state) { | |
185 | - final bloc = BlocProvider.of<LessonBloc>(context); | |
186 | - bool isSelected = bloc.currentPageIndex.floor() == index; | |
187 | - Matrix4 matrix4 = Matrix4.identity(); | |
188 | - if (index == bloc.currentPageIndex.floor()) { | |
189 | - //当前的item | |
190 | - double currScale = (1 - (bloc.currentPageIndex - index) * (1 - _scale)).toDouble(); | |
191 | - var currTrans = _numItemHeight * (1 - currScale) / 2; | |
192 | - | |
193 | - matrix4 = Matrix4.diagonal3Values(1.0, currScale, 1.0) | |
194 | - ..setTranslationRaw(0.0, currTrans, 0.0); | |
195 | - } else if (index == bloc.currentPageIndex.floor() + 1) { | |
196 | - //右边的item | |
197 | - var currScale = _scale + (bloc.currentPageIndex - index + 1) * (1 - _scale); | |
198 | - var currTrans = _numItemHeight * (1 - currScale) / 2; | |
199 | - | |
200 | - matrix4 = Matrix4.diagonal3Values(1.0, currScale, 1.0) | |
201 | - ..setTranslationRaw(0.0, currTrans, 0.0); | |
202 | - } else if (index == bloc.currentPageIndex - 1) { | |
203 | - //左边 | |
204 | - var currScale = (1 - (bloc.currentPageIndex - index) * (1 - _scale)).toDouble(); | |
205 | - var currTrans = _numItemHeight * (1 - currScale) / 2; | |
206 | - | |
207 | - matrix4 = Matrix4.diagonal3Values(1.0, currScale, 1.0) | |
208 | - ..setTranslationRaw(0.0, currTrans, 0.0); | |
209 | - } else { | |
210 | - //其他,不在屏幕显示的item | |
211 | - matrix4 = Matrix4.diagonal3Values(1.0, _scale, 1.0) | |
212 | - ..setTranslationRaw(0.0, _numItemHeight * (1 - _scale) / 2, 0.0); | |
213 | - } | |
214 | - | |
215 | - return Transform( | |
216 | - transform: matrix4, | |
217 | - child: Container( | |
218 | - color: isSelected?Colors.red:Colors.yellow, | |
219 | - ), | |
220 | - ); | |
221 | - }); | |
222 | 174 | } |
223 | 175 | \ No newline at end of file | ... | ... |
lib/pages/listen/bloc/listen_bloc.dart
1 | +import 'dart:convert'; | |
1 | 2 | |
2 | 3 | import 'package:flutter/cupertino.dart'; |
3 | 4 | import 'package:flutter_bloc/flutter_bloc.dart'; |
5 | +import 'package:flutter_easyloading/flutter_easyloading.dart'; | |
6 | +import 'package:wow_english/common/request/dao/listen_dao.dart'; | |
7 | +import 'package:wow_english/common/request/exception.dart'; | |
8 | +import 'package:wow_english/models/listen_entity.dart'; | |
9 | +import 'package:wow_english/utils/loading.dart'; | |
4 | 10 | |
5 | 11 | part 'listen_event.dart'; |
6 | 12 | part 'listen_state.dart'; |
7 | 13 | |
8 | 14 | class ListenBloc extends Bloc<ListenEvent, ListenState> { |
15 | + | |
16 | + final List<ListenEntity?> _listData = []; | |
17 | + List<ListenEntity?> get listData => _listData; | |
18 | + | |
9 | 19 | ListenBloc() : super(ListenInitial()) { |
10 | 20 | on<ListenEvent>((event, emit) { |
11 | 21 | // TODO: implement event handler |
12 | 22 | }); |
13 | 23 | } |
24 | + | |
25 | + Future<void> requestData() async { | |
26 | + try { | |
27 | + await loading(() async { | |
28 | + List<String> list = await ListenDao.listen()??[]; | |
29 | + if (list.isNotEmpty) { | |
30 | + for (String jsonStr in list) { | |
31 | + ListenEntity? data = ListenEntity.fromJson(jsonDecode(jsonStr)); | |
32 | + _listData.add(data); | |
33 | + } | |
34 | + } | |
35 | + emit(RequestListenDataState()); | |
36 | + }); | |
37 | + } catch (e) { | |
38 | + if (e is ApiException) { | |
39 | + EasyLoading.showToast(e.message??'请求失败,请检查网络连接'); | |
40 | + } | |
41 | + } | |
42 | + } | |
43 | + | |
14 | 44 | } | ... | ... |
lib/pages/listen/bloc/listen_state.dart
lib/pages/listen/listen_page.dart
... | ... | @@ -2,6 +2,7 @@ import 'package:flutter/material.dart'; |
2 | 2 | import 'package:flutter_bloc/flutter_bloc.dart'; |
3 | 3 | import 'package:flutter_screenutil/flutter_screenutil.dart'; |
4 | 4 | import 'package:wow_english/common/widgets/we_app_bar.dart'; |
5 | +import 'package:wow_english/route/route.dart'; | |
5 | 6 | |
6 | 7 | import 'bloc/listen_bloc.dart'; |
7 | 8 | import 'widgets/listen_item_widget.dart'; |
... | ... | @@ -12,7 +13,7 @@ class ListenPage extends StatelessWidget { |
12 | 13 | @override |
13 | 14 | Widget build(BuildContext context) { |
14 | 15 | return BlocProvider( |
15 | - create: (context) => ListenBloc(), | |
16 | + create: (context) => ListenBloc()..requestData(), | |
16 | 17 | child: _ListenPageView(), |
17 | 18 | ); |
18 | 19 | } |
... | ... | @@ -37,15 +38,16 @@ class _ListenPageView extends StatelessWidget { |
37 | 38 | |
38 | 39 | Widget _listenView() => BlocBuilder<ListenBloc, ListenState>( |
39 | 40 | builder: (context, state) { |
41 | + final bloc = BlocProvider.of<ListenBloc>(context); | |
40 | 42 | return ListView.builder( |
41 | - itemCount: 10, | |
43 | + itemCount: bloc.listData.length, | |
42 | 44 | scrollDirection: Axis.horizontal, |
43 | 45 | padding: EdgeInsets.symmetric(horizontal: 30.w,vertical: 36.h), |
44 | 46 | itemBuilder: (BuildContext context,int index){ |
45 | 47 | return ListenItemWidget( |
46 | - isLock: (index < 5), | |
48 | + isLock: (index > 5), | |
47 | 49 | clickEvent: (){ |
48 | - | |
50 | + Navigator.of(context).pushNamed(AppRouteName.lookVideo,arguments: {'videoUrl':'https://cdn.cnbj1.fds.api.mi-img.com/mi-mall/7194236f31b2e1e3da0fe06cfed4ba2b.mp4'}); | |
49 | 51 | }); |
50 | 52 | }); |
51 | 53 | }); | ... | ... |
lib/pages/listen/widgets/listen_item_widget.dart
... | ... | @@ -32,16 +32,16 @@ class ListenItemWidget extends StatelessWidget { |
32 | 32 | width: 180.h, |
33 | 33 | fit: BoxFit.fill, |
34 | 34 | ), |
35 | - Offstage( | |
36 | - offstage: isLock, | |
35 | + Visibility( | |
36 | + visible: isLock, | |
37 | 37 | child: Container( |
38 | 38 | height: 180.h, |
39 | 39 | width: 180.h, |
40 | 40 | color: const Color.fromRGBO(1, 1, 0, 0.5), |
41 | 41 | ), |
42 | 42 | ), |
43 | - Offstage( | |
44 | - offstage: isLock, | |
43 | + Visibility( | |
44 | + visible: isLock, | |
45 | 45 | child: Image.asset( |
46 | 46 | 'listen_lock'.assetPng, |
47 | 47 | height: 36.h, | ... | ... |
lib/pages/video/lookvideo/look_video_page.dart
... | ... | @@ -5,7 +5,9 @@ import 'package:wow_english/pages/video/lookvideo/widgets/video_widget.dart'; |
5 | 5 | import 'bloc/look_video_bloc.dart'; |
6 | 6 | |
7 | 7 | class LookVideoPage extends StatefulWidget { |
8 | - const LookVideoPage({super.key}); | |
8 | + const LookVideoPage({super.key, this.videoUrl}); | |
9 | + | |
10 | + final String? videoUrl; | |
9 | 11 | |
10 | 12 | @override |
11 | 13 | State<StatefulWidget> createState() { |
... | ... | @@ -16,8 +18,8 @@ class LookVideoPage extends StatefulWidget { |
16 | 18 | class _LookVideoPageState extends State<LookVideoPage> { |
17 | 19 | @override |
18 | 20 | Widget build(BuildContext context) { |
19 | - return const VideoWidget( | |
20 | - videoUrl: 'https://cdn.cnbj1.fds.api.mi-img.com/mi-mall/7194236f31b2e1e3da0fe06cfed4ba2b.mp4', | |
21 | + return VideoWidget( | |
22 | + videoUrl: widget.videoUrl??'', | |
21 | 23 | ); |
22 | 24 | } |
23 | 25 | } | ... | ... |
lib/route/route.dart
... | ... | @@ -89,7 +89,8 @@ class AppRouter { |
89 | 89 | case AppRouteName.voiceAnswer: |
90 | 90 | return CupertinoPageRoute(builder: (_) => const VoiceAnswerPage()); |
91 | 91 | case AppRouteName.lookVideo: |
92 | - return CupertinoPageRoute(builder: (_) => const LookVideoPage()); | |
92 | + final videoUrl = (settings.arguments as Map)['videoUrl'] as String; | |
93 | + return CupertinoPageRoute(builder: (_) => LookVideoPage(videoUrl: videoUrl,)); | |
93 | 94 | case AppRouteName.setPwd: |
94 | 95 | final phoneNum = (settings.arguments as Map)['phoneNumber'] as String; |
95 | 96 | return CupertinoPageRoute(builder: (_) => SetPassWordPage(phoneNum: phoneNum)); | ... | ... |