Commit 07b173c9516b4255c731c5c0b50a786dc51caad6
1 parent
37063ced
feat:练习页上方进度信息改成进度条呈现
Showing
6 changed files
with
49 additions
and
26 deletions
lib/pages/practice/bloc/topic_picture_bloc.dart
@@ -80,7 +80,10 @@ class TopicPictureBloc | @@ -80,7 +80,10 @@ class TopicPictureBloc | ||
80 | 80 | ||
81 | final BuildContext context; | 81 | final BuildContext context; |
82 | 82 | ||
83 | - TopicPictureBloc(this.context, this.pageController, this.courseLessonId) | 83 | + final Color? moduleColor; |
84 | + | ||
85 | + TopicPictureBloc( | ||
86 | + this.context, this.pageController, this.courseLessonId, this.moduleColor) | ||
84 | : super(TopicPictureInitial()) { | 87 | : super(TopicPictureInitial()) { |
85 | on<CurrentPageIndexChangeEvent>(_pageControllerChange); | 88 | on<CurrentPageIndexChangeEvent>(_pageControllerChange); |
86 | on<VoicePlayStateChangeEvent>(_voicePlayStateChange); | 89 | on<VoicePlayStateChangeEvent>(_voicePlayStateChange); |
lib/pages/practice/topic_picture_page.dart
@@ -15,18 +15,17 @@ import 'bloc/topic_picture_bloc.dart'; | @@ -15,18 +15,17 @@ import 'bloc/topic_picture_bloc.dart'; | ||
15 | import 'widgets/practice_header_widget.dart'; | 15 | import 'widgets/practice_header_widget.dart'; |
16 | 16 | ||
17 | class TopicPicturePage extends StatelessWidget { | 17 | class TopicPicturePage extends StatelessWidget { |
18 | - const TopicPicturePage({super.key, this.courseLessonId}); | 18 | + const TopicPicturePage({super.key, this.courseLessonId, this.moduleColor}); |
19 | 19 | ||
20 | final String? courseLessonId; | 20 | final String? courseLessonId; |
21 | 21 | ||
22 | + final Color? moduleColor; | ||
23 | + | ||
22 | @override | 24 | @override |
23 | Widget build(BuildContext context) { | 25 | Widget build(BuildContext context) { |
24 | return BlocProvider( | 26 | return BlocProvider( |
25 | create: (context) => TopicPictureBloc( | 27 | create: (context) => TopicPictureBloc( |
26 | - context, | ||
27 | - PageController(), | ||
28 | - courseLessonId ?? '', | ||
29 | - ) | 28 | + context, PageController(), courseLessonId ?? '', moduleColor) |
30 | ..add(InitBlocEvent()) | 29 | ..add(InitBlocEvent()) |
31 | ..add(RequestDataEvent()) | 30 | ..add(RequestDataEvent()) |
32 | ..add(XSVoiceInitEvent({ | 31 | ..add(XSVoiceInitEvent({ |
@@ -70,7 +69,9 @@ class _TopicPicturePage extends StatelessWidget { | @@ -70,7 +69,9 @@ class _TopicPicturePage extends StatelessWidget { | ||
70 | Column( | 69 | Column( |
71 | children: [ | 70 | children: [ |
72 | PracticeHeaderWidget( | 71 | PracticeHeaderWidget( |
73 | - title: '${bloc.currentPage}/${bloc.entity?.topics?.length}', | 72 | + color: bloc.moduleColor, |
73 | + progress: bloc.currentPage, | ||
74 | + total: bloc.entity?.topics?.length ?? 0, | ||
74 | onTap: () { | 75 | onTap: () { |
75 | popPage(data: { | 76 | popPage(data: { |
76 | 'currentStep': bloc.currentPage, | 77 | 'currentStep': bloc.currentPage, |
lib/pages/practice/widgets/practice_header_widget.dart
1 | import 'package:flutter/material.dart'; | 1 | import 'package:flutter/material.dart'; |
2 | import 'package:flutter_screenutil/flutter_screenutil.dart'; | 2 | import 'package:flutter_screenutil/flutter_screenutil.dart'; |
3 | +import 'package:percent_indicator/linear_percent_indicator.dart'; | ||
3 | import 'package:wow_english/common/extension/string_extension.dart'; | 4 | import 'package:wow_english/common/extension/string_extension.dart'; |
4 | 5 | ||
5 | class PracticeHeaderWidget extends StatelessWidget { | 6 | class PracticeHeaderWidget extends StatelessWidget { |
6 | - const PracticeHeaderWidget({super.key, required this.onTap, this.title = ''}); | 7 | + const PracticeHeaderWidget( |
8 | + {super.key, | ||
9 | + required this.onTap, | ||
10 | + this.color, | ||
11 | + required this.total, | ||
12 | + this.progress = 0}); | ||
7 | 13 | ||
8 | final Function() onTap; | 14 | final Function() onTap; |
9 | 15 | ||
10 | - final String title; | 16 | + ///进度条颜色(阶段颜色) |
17 | + final Color? color; | ||
18 | + | ||
19 | + ///进度条总长度 | ||
20 | + final int total; | ||
21 | + | ||
22 | + ///进度条当前长度 | ||
23 | + final int progress; | ||
11 | 24 | ||
12 | @override | 25 | @override |
13 | Widget build(BuildContext context) { | 26 | Widget build(BuildContext context) { |
@@ -26,21 +39,19 @@ class PracticeHeaderWidget extends StatelessWidget { | @@ -26,21 +39,19 @@ class PracticeHeaderWidget extends StatelessWidget { | ||
26 | ), | 39 | ), |
27 | centerTitle: true, | 40 | centerTitle: true, |
28 | title: Container( | 41 | title: Container( |
29 | - height: 20.h, | ||
30 | - width: 100.w, // 容器宽度 | 42 | + height: 10.h, |
43 | + width: 150.w, // 容器宽度 | ||
31 | // padding: EdgeInsets.symmetric(horizontal: 27.w, vertical: 10.h), | 44 | // padding: EdgeInsets.symmetric(horizontal: 27.w, vertical: 10.h), |
32 | alignment: Alignment.center, | 45 | alignment: Alignment.center, |
33 | - decoration: BoxDecoration( | ||
34 | - color: const Color(0xFF00B6F1), | ||
35 | - borderRadius: BorderRadius.circular(20.r), | ||
36 | - border: Border.all( | ||
37 | - width: 1.0, | ||
38 | - color: const Color(0xFF333333), | ||
39 | - ), | ||
40 | - ), | ||
41 | - child: Text( | ||
42 | - title, | ||
43 | - style: TextStyle(fontSize: 15.sp, color: Colors.white), | 46 | + child: LinearPercentIndicator( |
47 | + animation: true, | ||
48 | + lineHeight: 10.h, | ||
49 | + animationDuration: 250, | ||
50 | + animateFromLastPercent: true, | ||
51 | + percent: total > 0 ? progress / total : 0, | ||
52 | + // center: Text('$progress/$total}'), | ||
53 | + barRadius: const Radius.circular(5), | ||
54 | + progressColor: color, | ||
44 | ), | 55 | ), |
45 | ), | 56 | ), |
46 | )); | 57 | )); |
lib/pages/section/section_page.dart
@@ -136,9 +136,12 @@ class _SectionPageView extends StatelessWidget { | @@ -136,9 +136,12 @@ class _SectionPageView extends StatelessWidget { | ||
136 | clickController.playMusicAndPerformAction( | 136 | clickController.playMusicAndPerformAction( |
137 | context, AudioPlayerUtilType.quizTime, () async { | 137 | context, AudioPlayerUtilType.quizTime, () async { |
138 | await bloc.requestEnterClass(courseLessonId, () { | 138 | await bloc.requestEnterClass(courseLessonId, () { |
139 | - pushNamed(AppRouteName.topicPic, | ||
140 | - arguments: {'courseLessonId': courseLessonId}) | ||
141 | - .then((value) { | 139 | + pushNamed(AppRouteName.topicPic, arguments: { |
140 | + 'courseLessonId': courseLessonId, | ||
141 | + 'moduleColor': CourseModuleModel( | ||
142 | + bloc.courseUnitEntity.courseModuleCode ?? 'Phase-1') | ||
143 | + .color | ||
144 | + }).then((value) { | ||
142 | if (value != null) { | 145 | if (value != null) { |
143 | Map<String, dynamic> dataMap = | 146 | Map<String, dynamic> dataMap = |
144 | value as Map<String, dynamic>; | 147 | value as Map<String, dynamic>; |
lib/route/route.dart
@@ -183,12 +183,15 @@ class AppRouter { | @@ -183,12 +183,15 @@ class AppRouter { | ||
183 | });*/ | 183 | });*/ |
184 | case AppRouteName.topicPic: | 184 | case AppRouteName.topicPic: |
185 | var courseLessonId = ''; | 185 | var courseLessonId = ''; |
186 | + Color? moduleColor; | ||
186 | if (settings.arguments != null) { | 187 | if (settings.arguments != null) { |
187 | courseLessonId = | 188 | courseLessonId = |
188 | (settings.arguments as Map)['courseLessonId'] as String; | 189 | (settings.arguments as Map)['courseLessonId'] as String; |
190 | + moduleColor = (settings.arguments as Map)['moduleColor'] as Color?; | ||
189 | } | 191 | } |
190 | return CupertinoPageRoute( | 192 | return CupertinoPageRoute( |
191 | - builder: (_) => TopicPicturePage(courseLessonId: courseLessonId)); | 193 | + builder: (_) => TopicPicturePage( |
194 | + courseLessonId: courseLessonId, moduleColor: moduleColor)); | ||
192 | case AppRouteName.lookVideo: | 195 | case AppRouteName.lookVideo: |
193 | final videoUrl = (settings.arguments as Map)['videoUrl'] as String?; | 196 | final videoUrl = (settings.arguments as Map)['videoUrl'] as String?; |
194 | final title = (settings.arguments as Map)['title'] as String?; | 197 | final title = (settings.arguments as Map)['title'] as String?; |
pubspec.yaml
@@ -116,6 +116,8 @@ dependencies: | @@ -116,6 +116,8 @@ dependencies: | ||
116 | umeng_apm_sdk: ^2.2.1 | 116 | umeng_apm_sdk: ^2.2.1 |
117 | # 嵌套滚动 https://pub.dev/packages/nested_scroll_views | 117 | # 嵌套滚动 https://pub.dev/packages/nested_scroll_views |
118 | nested_scroll_views: ^0.0.10 | 118 | nested_scroll_views: ^0.0.10 |
119 | + # 进度条组件 https://pub.dev/packages/percent_indicator 主要看重其支持的进度动画效果 | ||
120 | + percent_indicator: ^4.2.3 | ||
119 | 121 | ||
120 | dev_dependencies: | 122 | dev_dependencies: |
121 | build_runner: ^2.4.4 | 123 | build_runner: ^2.4.4 |