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 | 80 | |
| 81 | 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 | 87 | : super(TopicPictureInitial()) { |
| 85 | 88 | on<CurrentPageIndexChangeEvent>(_pageControllerChange); |
| 86 | 89 | on<VoicePlayStateChangeEvent>(_voicePlayStateChange); | ... | ... |
lib/pages/practice/topic_picture_page.dart
| ... | ... | @@ -15,18 +15,17 @@ import 'bloc/topic_picture_bloc.dart'; |
| 15 | 15 | import 'widgets/practice_header_widget.dart'; |
| 16 | 16 | |
| 17 | 17 | class TopicPicturePage extends StatelessWidget { |
| 18 | - const TopicPicturePage({super.key, this.courseLessonId}); | |
| 18 | + const TopicPicturePage({super.key, this.courseLessonId, this.moduleColor}); | |
| 19 | 19 | |
| 20 | 20 | final String? courseLessonId; |
| 21 | 21 | |
| 22 | + final Color? moduleColor; | |
| 23 | + | |
| 22 | 24 | @override |
| 23 | 25 | Widget build(BuildContext context) { |
| 24 | 26 | return BlocProvider( |
| 25 | 27 | create: (context) => TopicPictureBloc( |
| 26 | - context, | |
| 27 | - PageController(), | |
| 28 | - courseLessonId ?? '', | |
| 29 | - ) | |
| 28 | + context, PageController(), courseLessonId ?? '', moduleColor) | |
| 30 | 29 | ..add(InitBlocEvent()) |
| 31 | 30 | ..add(RequestDataEvent()) |
| 32 | 31 | ..add(XSVoiceInitEvent({ |
| ... | ... | @@ -70,7 +69,9 @@ class _TopicPicturePage extends StatelessWidget { |
| 70 | 69 | Column( |
| 71 | 70 | children: [ |
| 72 | 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 | 75 | onTap: () { |
| 75 | 76 | popPage(data: { |
| 76 | 77 | 'currentStep': bloc.currentPage, | ... | ... |
lib/pages/practice/widgets/practice_header_widget.dart
| 1 | 1 | import 'package:flutter/material.dart'; |
| 2 | 2 | import 'package:flutter_screenutil/flutter_screenutil.dart'; |
| 3 | +import 'package:percent_indicator/linear_percent_indicator.dart'; | |
| 3 | 4 | import 'package:wow_english/common/extension/string_extension.dart'; |
| 4 | 5 | |
| 5 | 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 | 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 | 25 | @override |
| 13 | 26 | Widget build(BuildContext context) { |
| ... | ... | @@ -26,21 +39,19 @@ class PracticeHeaderWidget extends StatelessWidget { |
| 26 | 39 | ), |
| 27 | 40 | centerTitle: true, |
| 28 | 41 | title: Container( |
| 29 | - height: 20.h, | |
| 30 | - width: 100.w, // 容器宽度 | |
| 42 | + height: 10.h, | |
| 43 | + width: 150.w, // 容器宽度 | |
| 31 | 44 | // padding: EdgeInsets.symmetric(horizontal: 27.w, vertical: 10.h), |
| 32 | 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 | 136 | clickController.playMusicAndPerformAction( |
| 137 | 137 | context, AudioPlayerUtilType.quizTime, () async { |
| 138 | 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 | 145 | if (value != null) { |
| 143 | 146 | Map<String, dynamic> dataMap = |
| 144 | 147 | value as Map<String, dynamic>; | ... | ... |
lib/route/route.dart
| ... | ... | @@ -183,12 +183,15 @@ class AppRouter { |
| 183 | 183 | });*/ |
| 184 | 184 | case AppRouteName.topicPic: |
| 185 | 185 | var courseLessonId = ''; |
| 186 | + Color? moduleColor; | |
| 186 | 187 | if (settings.arguments != null) { |
| 187 | 188 | courseLessonId = |
| 188 | 189 | (settings.arguments as Map)['courseLessonId'] as String; |
| 190 | + moduleColor = (settings.arguments as Map)['moduleColor'] as Color?; | |
| 189 | 191 | } |
| 190 | 192 | return CupertinoPageRoute( |
| 191 | - builder: (_) => TopicPicturePage(courseLessonId: courseLessonId)); | |
| 193 | + builder: (_) => TopicPicturePage( | |
| 194 | + courseLessonId: courseLessonId, moduleColor: moduleColor)); | |
| 192 | 195 | case AppRouteName.lookVideo: |
| 193 | 196 | final videoUrl = (settings.arguments as Map)['videoUrl'] as String?; |
| 194 | 197 | final title = (settings.arguments as Map)['title'] as String?; | ... | ... |
pubspec.yaml
| ... | ... | @@ -116,6 +116,8 @@ dependencies: |
| 116 | 116 | umeng_apm_sdk: ^2.2.1 |
| 117 | 117 | # 嵌套滚动 https://pub.dev/packages/nested_scroll_views |
| 118 | 118 | nested_scroll_views: ^0.0.10 |
| 119 | + # 进度条组件 https://pub.dev/packages/percent_indicator 主要看重其支持的进度动画效果 | |
| 120 | + percent_indicator: ^4.2.3 | |
| 119 | 121 | |
| 120 | 122 | dev_dependencies: |
| 121 | 123 | build_runner: ^2.4.4 | ... | ... |