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,4 +22,24 @@ class Apis { | ||
22 | // GET /home/courseLesson | 22 | // GET /home/courseLesson |
23 | // 接口地址:https://app.apifox.com/link/project/2684751/apis/api-89897662 | 23 | // 接口地址:https://app.apifox.com/link/project/2684751/apis/api-89897662 |
24 | static const String courseLesson = 'home/courseLesson'; | 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,14 +3,14 @@ import 'package:wow_english/common/request/request_client.dart'; | ||
3 | 3 | ||
4 | class HomeDao { | 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 | return data; | 8 | return data; |
9 | } | 9 | } |
10 | 10 | ||
11 | ///课程列表 | 11 | ///课程列表 |
12 | static Future courseLesson() async { | 12 | static Future courseLesson() async { |
13 | - var data = requestClient.get(Apis.courseLesson); | 13 | + var data = await requestClient.get(Apis.courseLesson); |
14 | return data; | 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 | \ No newline at end of file | 11 | \ No newline at end of file |
lib/generated/json/base/json_convert_content.dart
@@ -4,6 +4,8 @@ | @@ -4,6 +4,8 @@ | ||
4 | 4 | ||
5 | // This file is automatically generated. DO NOT EDIT, all your changes would be lost. | 5 | // This file is automatically generated. DO NOT EDIT, all your changes would be lost. |
6 | import 'package:flutter/material.dart' show debugPrint; | 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 | import 'package:wow_english/models/user_entity.dart'; | 9 | import 'package:wow_english/models/user_entity.dart'; |
8 | 10 | ||
9 | JsonConvert jsonConvert = JsonConvert(); | 11 | JsonConvert jsonConvert = JsonConvert(); |
@@ -12,6 +14,8 @@ typedef EnumConvertFunction<T> = T Function(String value); | @@ -12,6 +14,8 @@ typedef EnumConvertFunction<T> = T Function(String value); | ||
12 | 14 | ||
13 | class JsonConvert { | 15 | class JsonConvert { |
14 | static final Map<String, JsonConvertFunction> convertFuncMap = { | 16 | static final Map<String, JsonConvertFunction> convertFuncMap = { |
17 | + (LessonEntity).toString(): LessonEntity.fromJson, | ||
18 | + (ListenEntity).toString(): ListenEntity.fromJson, | ||
15 | (UserEntity).toString(): UserEntity.fromJson, | 19 | (UserEntity).toString(): UserEntity.fromJson, |
16 | }; | 20 | }; |
17 | 21 | ||
@@ -91,12 +95,18 @@ List<T>? convertListNotNull<T>(dynamic value, {EnumConvertFunction? enumConvert} | @@ -91,12 +95,18 @@ List<T>? convertListNotNull<T>(dynamic value, {EnumConvertFunction? enumConvert} | ||
91 | 95 | ||
92 | //list is returned by type | 96 | //list is returned by type |
93 | static M? _getListChildType<M>(List<Map<String, dynamic>> data) { | 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 | if(<UserEntity>[] is M){ | 104 | if(<UserEntity>[] is M){ |
95 | return data.map<UserEntity>((Map<String, dynamic> e) => UserEntity.fromJson(e)).toList() as M; | 105 | return data.map<UserEntity>((Map<String, dynamic> e) => UserEntity.fromJson(e)).toList() as M; |
96 | } | 106 | } |
97 | 107 | ||
98 | debugPrint("${M.toString()} not found"); | 108 | debugPrint("${M.toString()} not found"); |
99 | - | 109 | + |
100 | return null; | 110 | return null; |
101 | } | 111 | } |
102 | 112 | ||
@@ -107,4 +117,4 @@ List<T>? convertListNotNull<T>(dynamic value, {EnumConvertFunction? enumConvert} | @@ -107,4 +117,4 @@ List<T>? convertListNotNull<T>(dynamic value, {EnumConvertFunction? enumConvert} | ||
107 | return jsonConvert.convert<M>(json); | 117 | return jsonConvert.convert<M>(json); |
108 | } | 118 | } |
109 | } | 119 | } |
110 | -} | 120 | -} |
121 | +} | ||
111 | \ No newline at end of file | 122 | \ No newline at end of file |
lib/generated/json/base/json_field.dart
@@ -14,12 +14,12 @@ class JSONField { | @@ -14,12 +14,12 @@ class JSONField { | ||
14 | 14 | ||
15 | //Whether to participate in toJson | 15 | //Whether to participate in toJson |
16 | final bool? serialize; | 16 | final bool? serialize; |
17 | - | 17 | + |
18 | //Whether to participate in fromMap | 18 | //Whether to participate in fromMap |
19 | final bool? deserialize; | 19 | final bool? deserialize; |
20 | - | 20 | + |
21 | //Enumeration or not | 21 | //Enumeration or not |
22 | final bool? isEnum; | 22 | final bool? isEnum; |
23 | - | 23 | + |
24 | const JSONField({this.name, this.serialize, this.deserialize, this.isEnum}); | 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 | \ No newline at end of file | 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 | \ No newline at end of file | 68 | \ No newline at end of file |
lib/generated/json/user_entity.g.dart
@@ -49,4 +49,4 @@ Map<String, dynamic> $UserEntityToJson(UserEntity entity) { | @@ -49,4 +49,4 @@ Map<String, dynamic> $UserEntityToJson(UserEntity entity) { | ||
49 | data['token'] = entity.token; | 49 | data['token'] = entity.token; |
50 | data['expireTime'] = entity.expireTime; | 50 | data['expireTime'] = entity.expireTime; |
51 | return data; | 51 | return data; |
52 | -} | 52 | -} |
53 | +} | ||
53 | \ No newline at end of file | 54 | \ No newline at end of file |
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 | \ No newline at end of file | 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 | \ No newline at end of file | 30 | \ No newline at end of file |
lib/pages/home/bloc/home_bloc.dart
1 | import 'package:flutter/cupertino.dart'; | 1 | import 'package:flutter/cupertino.dart'; |
2 | import 'package:flutter_bloc/flutter_bloc.dart'; | 2 | import 'package:flutter_bloc/flutter_bloc.dart'; |
3 | +import 'package:flutter_easyloading/flutter_easyloading.dart'; | ||
3 | import 'package:wow_english/common/request/dao/home_dao.dart'; | 4 | import 'package:wow_english/common/request/dao/home_dao.dart'; |
4 | import 'package:wow_english/common/request/exception.dart'; | 5 | import 'package:wow_english/common/request/exception.dart'; |
5 | import 'package:wow_english/utils/loading.dart'; | 6 | import 'package:wow_english/utils/loading.dart'; |
@@ -9,9 +10,7 @@ part 'home_state.dart'; | @@ -9,9 +10,7 @@ part 'home_state.dart'; | ||
9 | 10 | ||
10 | class HomeBloc extends Bloc<HomeEvent, HomeState> { | 11 | class HomeBloc extends Bloc<HomeEvent, HomeState> { |
11 | HomeBloc() : super(HomeInitial()) { | 12 | HomeBloc() : super(HomeInitial()) { |
12 | - on<HomeEvent>((event, emit) { | ||
13 | - // TODO: implement event handler | ||
14 | - }); | 13 | + on<RequestDataEvent>(_requestData); |
15 | } | 14 | } |
16 | 15 | ||
17 | Future<void> requestData() async { | 16 | Future<void> requestData() async { |
@@ -22,8 +21,22 @@ class HomeBloc extends Bloc<HomeEvent, HomeState> { | @@ -22,8 +21,22 @@ class HomeBloc extends Bloc<HomeEvent, HomeState> { | ||
22 | }); | 21 | }); |
23 | } catch (e) { | 22 | } catch (e) { |
24 | if (e is ApiException) { | 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 | import 'package:flutter/cupertino.dart'; | 3 | import 'package:flutter/cupertino.dart'; |
4 | +import 'package:flutter/foundation.dart'; | ||
2 | import 'package:flutter_bloc/flutter_bloc.dart'; | 5 | import 'package:flutter_bloc/flutter_bloc.dart'; |
3 | import 'package:wow_english/common/request/dao/home_dao.dart'; | 6 | import 'package:wow_english/common/request/dao/home_dao.dart'; |
4 | import 'package:wow_english/common/request/exception.dart'; | 7 | import 'package:wow_english/common/request/exception.dart'; |
8 | +import 'package:wow_english/models/lesson_entity.dart'; | ||
5 | import 'package:wow_english/utils/loading.dart'; | 9 | import 'package:wow_english/utils/loading.dart'; |
6 | 10 | ||
7 | part 'lesson_event.dart'; | 11 | part 'lesson_event.dart'; |
@@ -17,6 +21,9 @@ class LessonBloc extends Bloc<LessonEvent, LessonState> { | @@ -17,6 +21,9 @@ class LessonBloc extends Bloc<LessonEvent, LessonState> { | ||
17 | 21 | ||
18 | int get currentPageIndex => _currentPageIndex; | 22 | int get currentPageIndex => _currentPageIndex; |
19 | 23 | ||
24 | + List<LessonEntity?> _listData = []; | ||
25 | + List<LessonEntity?> get listData => _listData; | ||
26 | + | ||
20 | LessonBloc(this.pageIndex,this.pageController) : super(LessonInitial()) { | 27 | LessonBloc(this.pageIndex,this.pageController) : super(LessonInitial()) { |
21 | _currentPageIndex = pageIndex; | 28 | _currentPageIndex = pageIndex; |
22 | on<PageViewChangeIndexEvent>(_pageIndexChange); | 29 | on<PageViewChangeIndexEvent>(_pageIndexChange); |
@@ -25,7 +32,13 @@ class LessonBloc extends Bloc<LessonEvent, LessonState> { | @@ -25,7 +32,13 @@ class LessonBloc extends Bloc<LessonEvent, LessonState> { | ||
25 | Future<void> requestData() async { | 32 | Future<void> requestData() async { |
26 | try { | 33 | try { |
27 | await loading(() async { | 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 | emit(LessonDataLoadState()); | 42 | emit(LessonDataLoadState()); |
30 | }); | 43 | }); |
31 | } catch (e) { | 44 | } catch (e) { |
lib/pages/lessons/lesson_page.dart
@@ -77,7 +77,7 @@ class _LessonPageView extends StatelessWidget { | @@ -77,7 +77,7 @@ class _LessonPageView extends StatelessWidget { | ||
77 | SizedBox( | 77 | SizedBox( |
78 | height: _cardHeight, | 78 | height: _cardHeight, |
79 | child: PageView.builder( | 79 | child: PageView.builder( |
80 | - itemCount: 10, | 80 | + itemCount: bloc.listData.length, |
81 | controller: bloc.pageController, | 81 | controller: bloc.pageController, |
82 | onPageChanged: (int index) { | 82 | onPageChanged: (int index) { |
83 | bloc.add(PageViewChangeIndexEvent(index)); | 83 | bloc.add(PageViewChangeIndexEvent(index)); |
@@ -125,14 +125,6 @@ class _LessonPageView extends StatelessWidget { | @@ -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,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 | \ No newline at end of file | 175 | \ No newline at end of file |
lib/pages/listen/bloc/listen_bloc.dart
1 | +import 'dart:convert'; | ||
1 | 2 | ||
2 | import 'package:flutter/cupertino.dart'; | 3 | import 'package:flutter/cupertino.dart'; |
3 | import 'package:flutter_bloc/flutter_bloc.dart'; | 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 | part 'listen_event.dart'; | 11 | part 'listen_event.dart'; |
6 | part 'listen_state.dart'; | 12 | part 'listen_state.dart'; |
7 | 13 | ||
8 | class ListenBloc extends Bloc<ListenEvent, ListenState> { | 14 | class ListenBloc extends Bloc<ListenEvent, ListenState> { |
15 | + | ||
16 | + final List<ListenEntity?> _listData = []; | ||
17 | + List<ListenEntity?> get listData => _listData; | ||
18 | + | ||
9 | ListenBloc() : super(ListenInitial()) { | 19 | ListenBloc() : super(ListenInitial()) { |
10 | on<ListenEvent>((event, emit) { | 20 | on<ListenEvent>((event, emit) { |
11 | // TODO: implement event handler | 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
@@ -4,3 +4,5 @@ part of 'listen_bloc.dart'; | @@ -4,3 +4,5 @@ part of 'listen_bloc.dart'; | ||
4 | abstract class ListenState {} | 4 | abstract class ListenState {} |
5 | 5 | ||
6 | class ListenInitial extends ListenState {} | 6 | class ListenInitial extends ListenState {} |
7 | + | ||
8 | +class RequestListenDataState extends ListenState {} |
lib/pages/listen/listen_page.dart
@@ -2,6 +2,7 @@ import 'package:flutter/material.dart'; | @@ -2,6 +2,7 @@ import 'package:flutter/material.dart'; | ||
2 | import 'package:flutter_bloc/flutter_bloc.dart'; | 2 | import 'package:flutter_bloc/flutter_bloc.dart'; |
3 | import 'package:flutter_screenutil/flutter_screenutil.dart'; | 3 | import 'package:flutter_screenutil/flutter_screenutil.dart'; |
4 | import 'package:wow_english/common/widgets/we_app_bar.dart'; | 4 | import 'package:wow_english/common/widgets/we_app_bar.dart'; |
5 | +import 'package:wow_english/route/route.dart'; | ||
5 | 6 | ||
6 | import 'bloc/listen_bloc.dart'; | 7 | import 'bloc/listen_bloc.dart'; |
7 | import 'widgets/listen_item_widget.dart'; | 8 | import 'widgets/listen_item_widget.dart'; |
@@ -12,7 +13,7 @@ class ListenPage extends StatelessWidget { | @@ -12,7 +13,7 @@ class ListenPage extends StatelessWidget { | ||
12 | @override | 13 | @override |
13 | Widget build(BuildContext context) { | 14 | Widget build(BuildContext context) { |
14 | return BlocProvider( | 15 | return BlocProvider( |
15 | - create: (context) => ListenBloc(), | 16 | + create: (context) => ListenBloc()..requestData(), |
16 | child: _ListenPageView(), | 17 | child: _ListenPageView(), |
17 | ); | 18 | ); |
18 | } | 19 | } |
@@ -37,15 +38,16 @@ class _ListenPageView extends StatelessWidget { | @@ -37,15 +38,16 @@ class _ListenPageView extends StatelessWidget { | ||
37 | 38 | ||
38 | Widget _listenView() => BlocBuilder<ListenBloc, ListenState>( | 39 | Widget _listenView() => BlocBuilder<ListenBloc, ListenState>( |
39 | builder: (context, state) { | 40 | builder: (context, state) { |
41 | + final bloc = BlocProvider.of<ListenBloc>(context); | ||
40 | return ListView.builder( | 42 | return ListView.builder( |
41 | - itemCount: 10, | 43 | + itemCount: bloc.listData.length, |
42 | scrollDirection: Axis.horizontal, | 44 | scrollDirection: Axis.horizontal, |
43 | padding: EdgeInsets.symmetric(horizontal: 30.w,vertical: 36.h), | 45 | padding: EdgeInsets.symmetric(horizontal: 30.w,vertical: 36.h), |
44 | itemBuilder: (BuildContext context,int index){ | 46 | itemBuilder: (BuildContext context,int index){ |
45 | return ListenItemWidget( | 47 | return ListenItemWidget( |
46 | - isLock: (index < 5), | 48 | + isLock: (index > 5), |
47 | clickEvent: (){ | 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,16 +32,16 @@ class ListenItemWidget extends StatelessWidget { | ||
32 | width: 180.h, | 32 | width: 180.h, |
33 | fit: BoxFit.fill, | 33 | fit: BoxFit.fill, |
34 | ), | 34 | ), |
35 | - Offstage( | ||
36 | - offstage: isLock, | 35 | + Visibility( |
36 | + visible: isLock, | ||
37 | child: Container( | 37 | child: Container( |
38 | height: 180.h, | 38 | height: 180.h, |
39 | width: 180.h, | 39 | width: 180.h, |
40 | color: const Color.fromRGBO(1, 1, 0, 0.5), | 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 | child: Image.asset( | 45 | child: Image.asset( |
46 | 'listen_lock'.assetPng, | 46 | 'listen_lock'.assetPng, |
47 | height: 36.h, | 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,7 +5,9 @@ import 'package:wow_english/pages/video/lookvideo/widgets/video_widget.dart'; | ||
5 | import 'bloc/look_video_bloc.dart'; | 5 | import 'bloc/look_video_bloc.dart'; |
6 | 6 | ||
7 | class LookVideoPage extends StatefulWidget { | 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 | @override | 12 | @override |
11 | State<StatefulWidget> createState() { | 13 | State<StatefulWidget> createState() { |
@@ -16,8 +18,8 @@ class LookVideoPage extends StatefulWidget { | @@ -16,8 +18,8 @@ class LookVideoPage extends StatefulWidget { | ||
16 | class _LookVideoPageState extends State<LookVideoPage> { | 18 | class _LookVideoPageState extends State<LookVideoPage> { |
17 | @override | 19 | @override |
18 | Widget build(BuildContext context) { | 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,7 +89,8 @@ class AppRouter { | ||
89 | case AppRouteName.voiceAnswer: | 89 | case AppRouteName.voiceAnswer: |
90 | return CupertinoPageRoute(builder: (_) => const VoiceAnswerPage()); | 90 | return CupertinoPageRoute(builder: (_) => const VoiceAnswerPage()); |
91 | case AppRouteName.lookVideo: | 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 | case AppRouteName.setPwd: | 94 | case AppRouteName.setPwd: |
94 | final phoneNum = (settings.arguments as Map)['phoneNumber'] as String; | 95 | final phoneNum = (settings.arguments as Map)['phoneNumber'] as String; |
95 | return CupertinoPageRoute(builder: (_) => SetPassWordPage(phoneNum: phoneNum)); | 96 | return CupertinoPageRoute(builder: (_) => SetPassWordPage(phoneNum: phoneNum)); |