Commit b1869cf8c5a103abd2206171c56033fe68ce78c8

Authored by biao
1 parent d5fb5080

背景音乐添加

lib/pages/games/bloc.dart
@@ -2,17 +2,17 @@ import 'package:bloc/bloc.dart'; @@ -2,17 +2,17 @@ import 'package:bloc/bloc.dart';
2 import 'package:flutter/cupertino.dart'; 2 import 'package:flutter/cupertino.dart';
3 import 'package:flutter/services.dart'; 3 import 'package:flutter/services.dart';
4 import 'package:wow_english/common/extension/string_extension.dart'; 4 import 'package:wow_english/common/extension/string_extension.dart';
  5 +import 'package:wow_english/utils/audioplayer_util.dart';
5 6
6 import 'event.dart'; 7 import 'event.dart';
7 import 'game_entity.dart'; 8 import 'game_entity.dart';
8 import 'state.dart'; 9 import 'state.dart';
9 10
10 class GamesBloc extends Bloc<GamesEvent, GamesState> { 11 class GamesBloc extends Bloc<GamesEvent, GamesState> {
11 -  
12 late MethodChannel _methodChannel; 12 late MethodChannel _methodChannel;
13 13
14 //手动初始化4个GameEntity对象 14 //手动初始化4个GameEntity对象
15 - final List<GameEntity> _games = [ 15 + final List<GameEntity> _games = [
16 GameEntity() 16 GameEntity()
17 ..id = 1 17 ..id = 1
18 ..imageName = 'game_food_1'.assetPng 18 ..imageName = 'game_food_1'.assetPng
@@ -31,7 +31,7 @@ class GamesBloc extends Bloc&lt;GamesEvent, GamesState&gt; { @@ -31,7 +31,7 @@ class GamesBloc extends Bloc&lt;GamesEvent, GamesState&gt; {
31 ..name = 'Animal' 31 ..name = 'Animal'
32 ]; 32 ];
33 33
34 - List<GameEntity> get listData => _games; 34 + List<GameEntity> get listData => _games;
35 35
36 GamesBloc() : super(GamesState().init()) { 36 GamesBloc() : super(GamesState().init()) {
37 on<InitEvent>(_init); 37 on<InitEvent>(_init);
@@ -39,13 +39,16 @@ class GamesBloc extends Bloc&lt;GamesEvent, GamesState&gt; { @@ -39,13 +39,16 @@ class GamesBloc extends Bloc&lt;GamesEvent, GamesState&gt; {
39 } 39 }
40 40
41 void _init(InitEvent event, Emitter<GamesState> emit) async { 41 void _init(InitEvent event, Emitter<GamesState> emit) async {
  42 + AudioPlayerUtil.getInstance().playAudio(AudioPlayerUtilType.inMyTummy);
42 emit(state.clone()); 43 emit(state.clone());
43 } 44 }
44 45
45 void _gotoGamePage(GotoGamePageEvent event, Emitter<GamesState> emit) async { 46 void _gotoGamePage(GotoGamePageEvent event, Emitter<GamesState> emit) async {
  47 + AudioPlayerUtil.getInstance().pause();
46 try { 48 try {
47 _methodChannel = const MethodChannel('wow_english/game_method_channel'); 49 _methodChannel = const MethodChannel('wow_english/game_method_channel');
48 - await _methodChannel.invokeMethod('openGamePage', { "gameId": event.gameId }); 50 + await _methodChannel
  51 + .invokeMethod('openGamePage', {"gameId": event.gameId});
49 } on PlatformException catch (e) { 52 } on PlatformException catch (e) {
50 debugPrint("Failed to go to native page: '${e.message}'."); 53 debugPrint("Failed to go to native page: '${e.message}'.");
51 } 54 }
lib/pages/home/bloc.dart
@@ -2,6 +2,7 @@ import &#39;package:audioplayers/audioplayers.dart&#39;; @@ -2,6 +2,7 @@ import &#39;package:audioplayers/audioplayers.dart&#39;;
2 import 'package:bloc/bloc.dart'; 2 import 'package:bloc/bloc.dart';
3 import 'package:wow_english/common/core/user_util.dart'; 3 import 'package:wow_english/common/core/user_util.dart';
4 import 'package:wow_english/common/extension/string_extension.dart'; 4 import 'package:wow_english/common/extension/string_extension.dart';
  5 +import 'package:wow_english/utils/audioplayer_util.dart';
5 6
6 import '../../common/core/app_config_helper.dart'; 7 import '../../common/core/app_config_helper.dart';
7 import '../../common/request/dao/system_dao.dart'; 8 import '../../common/request/dao/system_dao.dart';
@@ -17,16 +18,10 @@ class HomeBloc extends Bloc&lt;HomeEvent, HomeState&gt; { @@ -17,16 +18,10 @@ class HomeBloc extends Bloc&lt;HomeEvent, HomeState&gt; {
17 } 18 }
18 19
19 bool exchangeResult = false; 20 bool exchangeResult = false;
20 - late AudioPlayer audioPlayer;  
21 - late AudioPlayer studyPlayer;  
22 - late AudioPlayer gamePlayer;  
23 21
24 void _init(InitEvent event, Emitter<HomeState> emit) async { 22 void _init(InitEvent event, Emitter<HomeState> emit) async {
25 if (UserUtil.isLogined()) { 23 if (UserUtil.isLogined()) {
26 - audioPlayer = AudioPlayer(playerId: 'audio');  
27 - gamePlayer = AudioPlayer(playerId: 'game');  
28 - studyPlayer = AudioPlayer(playerId: 'study');  
29 - audioPlayer.play(AssetSource('welcome_to_wow'.assetMp3)); 24 + AudioPlayerUtil.getInstance().playAudio(AudioPlayerUtilType.welcomeToWow);
30 } 25 }
31 await _checkUpdate(emit); 26 await _checkUpdate(emit);
32 } 27 }
lib/pages/home/view.dart
@@ -12,6 +12,7 @@ import &#39;package:wow_english/pages/home/state.dart&#39;; @@ -12,6 +12,7 @@ import &#39;package:wow_english/pages/home/state.dart&#39;;
12 import 'package:wow_english/pages/home/widgets/BaseHomeHeaderWidget.dart'; 12 import 'package:wow_english/pages/home/widgets/BaseHomeHeaderWidget.dart';
13 import 'package:wow_english/pages/shop/exchane/bloc/exchange_lesson_bloc.dart'; 13 import 'package:wow_english/pages/shop/exchane/bloc/exchange_lesson_bloc.dart';
14 import 'package:wow_english/pages/user/bloc/user_bloc.dart'; 14 import 'package:wow_english/pages/user/bloc/user_bloc.dart';
  15 +import 'package:wow_english/utils/audioplayer_util.dart';
15 16
16 import '../../common/core/user_util.dart'; 17 import '../../common/core/user_util.dart';
17 import '../../common/dialogs/show_dialog.dart'; 18 import '../../common/dialogs/show_dialog.dart';
@@ -60,6 +61,8 @@ class _HomePageView extends StatelessWidget { @@ -60,6 +61,8 @@ class _HomePageView extends StatelessWidget {
60 children: [ 61 children: [
61 BaseHomeHeaderWidget( 62 BaseHomeHeaderWidget(
62 callBack: (value) => { 63 callBack: (value) => {
  64 + AudioPlayerUtil.getInstance()
  65 + .playAudio(AudioPlayerUtilType.touch),
63 bloc.exchangeResult = value['exchange'], 66 bloc.exchangeResult = value['exchange'],
64 bloc.add(ExchangeSuccessEvent()) 67 bloc.add(ExchangeSuccessEvent())
65 }), 68 }),
@@ -71,8 +74,8 @@ class _HomePageView extends StatelessWidget { @@ -71,8 +74,8 @@ class _HomePageView extends StatelessWidget {
71 child: GestureDetector( 74 child: GestureDetector(
72 onTap: () { 75 onTap: () {
73 _checkPermission(() { 76 _checkPermission(() {
74 - bloc.studyPlayer  
75 - .play(AssetSource('class_time'.assetMp3)); 77 + AudioPlayerUtil.getInstance()
  78 + .playAudio(AudioPlayerUtilType.classTime);
76 Future.delayed(const Duration(seconds: 1), () { 79 Future.delayed(const Duration(seconds: 1), () {
77 pushNamed(AppRouteName.courseUnit) 80 pushNamed(AppRouteName.courseUnit)
78 .then((value) => { 81 .then((value) => {
@@ -108,29 +111,38 @@ class _HomePageView extends StatelessWidget { @@ -108,29 +111,38 @@ class _HomePageView extends StatelessWidget {
108 ), 111 ),
109 ), 112 ),
110 ), 113 ),
111 - Expanded(  
112 - child: BlocBuilder<UserBloc, UserState>(  
113 - builder: (context, userState) {  
114 - return GestureDetector(  
115 - onTap: () {  
116 - _checkPermission(() {  
117 - Navigator.of(context).pushNamed(  
118 - AppRouteName.webView,  
119 - arguments: {  
120 - 'urlStr': AppConsts.xiaoeShopUrl,  
121 - 'webViewTitle': 'Wow精选'  
122 - });  
123 - }, bloc);  
124 - },  
125 - child: Column(  
126 - mainAxisAlignment: MainAxisAlignment.center,  
127 - children: [  
128 - Image.asset('xe_shop'.assetPng,  
129 - width: 140.5.w, height: 172.h),  
130 - 44.verticalSpace  
131 - ],  
132 - ));  
133 - }), 114 + Offstage(
  115 + offstage: AppConfigHelper.shouldHidePay() ||
  116 + !UserUtil.isLogined(),
  117 + child: Expanded(
  118 + child: BlocBuilder<UserBloc, UserState>(
  119 + builder: (context, userState) {
  120 + return GestureDetector(
  121 + onTap: () {
  122 + _checkPermission(() {
  123 + AudioPlayerUtil.getInstance().pause();
  124 + Navigator.of(context).pushNamed(
  125 + AppRouteName.webView,
  126 + arguments: {
  127 + 'urlStr': AppConsts.xiaoeShopUrl,
  128 + 'webViewTitle': 'Wow精选'
  129 + }).then((value) => {
  130 + AudioPlayerUtil.getInstance()
  131 + .playAudio(
  132 + AudioPlayerUtilType.touch),
  133 + });
  134 + }, bloc);
  135 + },
  136 + child: Column(
  137 + mainAxisAlignment: MainAxisAlignment.center,
  138 + children: [
  139 + Image.asset('xe_shop'.assetPng,
  140 + width: 140.5.w, height: 172.h),
  141 + 44.verticalSpace
  142 + ],
  143 + ));
  144 + }),
  145 + ),
134 ), 146 ),
135 Expanded( 147 Expanded(
136 child: BlocBuilder<UserBloc, UserState>( 148 child: BlocBuilder<UserBloc, UserState>(
@@ -138,9 +150,14 @@ class _HomePageView extends StatelessWidget { @@ -138,9 +150,14 @@ class _HomePageView extends StatelessWidget {
138 return GestureDetector( 150 return GestureDetector(
139 onTap: () { 151 onTap: () {
140 _checkPermission(() { 152 _checkPermission(() {
141 - bloc.gamePlayer.play(  
142 - AssetSource('game_time'.assetMp3));  
143 - pushNamed(AppRouteName.games); 153 + AudioPlayerUtil.getInstance().playAudio(
  154 + AudioPlayerUtilType.gameTime);
  155 + pushNamed(AppRouteName.games)
  156 + .then((value) => {
  157 + AudioPlayerUtil.getInstance()
  158 + .playAudio(AudioPlayerUtilType
  159 + .touch),
  160 + });
144 }, bloc); 161 }, bloc);
145 }, 162 },
146 child: Column( 163 child: Column(
@@ -189,6 +206,8 @@ class _HomePageView extends StatelessWidget { @@ -189,6 +206,8 @@ class _HomePageView extends StatelessWidget {
189 }, rightTap: () { 206 }, rightTap: () {
190 popPage(); 207 popPage();
191 pushNamed(AppRouteName.shop).then((value) { 208 pushNamed(AppRouteName.shop).then((value) {
  209 + AudioPlayerUtil.getInstance()
  210 + .playAudio(AudioPlayerUtilType.touch);
192 if (value != null) { 211 if (value != null) {
193 bloc.exchangeResult = value['exchange']; 212 bloc.exchangeResult = value['exchange'];
194 bloc.add(ExchangeSuccessEvent()); 213 bloc.add(ExchangeSuccessEvent());
lib/pages/home/widgets/BaseHomeHeaderWidget.dart
@@ -3,6 +3,7 @@ import &#39;package:flutter_bloc/flutter_bloc.dart&#39;; @@ -3,6 +3,7 @@ import &#39;package:flutter_bloc/flutter_bloc.dart&#39;;
3 import 'package:flutter_screenutil/flutter_screenutil.dart'; 3 import 'package:flutter_screenutil/flutter_screenutil.dart';
4 import 'package:wow_english/common/core/app_config_helper.dart'; 4 import 'package:wow_english/common/core/app_config_helper.dart';
5 import 'package:wow_english/common/extension/string_extension.dart'; 5 import 'package:wow_english/common/extension/string_extension.dart';
  6 +import 'package:wow_english/utils/audioplayer_util.dart';
6 7
7 import '../../../common/core/user_util.dart'; 8 import '../../../common/core/user_util.dart';
8 import '../../../models/course_entity.dart'; 9 import '../../../models/course_entity.dart';
@@ -84,6 +85,7 @@ class BaseHomeHeaderWidget extends StatelessWidget { @@ -84,6 +85,7 @@ class BaseHomeHeaderWidget extends StatelessWidget {
84 !UserUtil.isLogined(), 85 !UserUtil.isLogined(),
85 child: GestureDetector( 86 child: GestureDetector(
86 onTap: () => { 87 onTap: () => {
  88 + AudioPlayerUtil.getInstance().pause(),
87 pushNamed(AppRouteName.shop).then((value) { 89 pushNamed(AppRouteName.shop).then((value) {
88 if (value != null) { 90 if (value != null) {
89 if (callBack == null) { 91 if (callBack == null) {
@@ -115,6 +117,7 @@ class BaseHomeHeaderWidget extends StatelessWidget { @@ -115,6 +117,7 @@ class BaseHomeHeaderWidget extends StatelessWidget {
115 117
116 void onUserClick() { 118 void onUserClick() {
117 if (UserUtil.isLogined()) { 119 if (UserUtil.isLogined()) {
  120 + AudioPlayerUtil.getInstance().pause();
118 pushNamed(AppRouteName.user).then((value) { 121 pushNamed(AppRouteName.user).then((value) {
119 if (value != null) { 122 if (value != null) {
120 if (callBack == null) { 123 if (callBack == null) {
lib/pages/section/bloc/section_bloc.dart
@@ -9,6 +9,7 @@ import &#39;package:wow_english/common/request/dao/lesson_dao.dart&#39;; @@ -9,6 +9,7 @@ import &#39;package:wow_english/common/request/dao/lesson_dao.dart&#39;;
9 import 'package:wow_english/common/request/exception.dart'; 9 import 'package:wow_english/common/request/exception.dart';
10 import 'package:wow_english/common/request/dao/listen_dao.dart'; 10 import 'package:wow_english/common/request/dao/listen_dao.dart';
11 import 'package:wow_english/models/course_process_entity.dart'; 11 import 'package:wow_english/models/course_process_entity.dart';
  12 +import 'package:wow_english/utils/audioplayer_util.dart';
12 import 'package:wow_english/utils/loading.dart'; 13 import 'package:wow_english/utils/loading.dart';
13 import 'package:wow_english/utils/toast_util.dart'; 14 import 'package:wow_english/utils/toast_util.dart';
14 15
@@ -45,8 +46,6 @@ class SectionBloc extends Bloc&lt;SectionEvent, SectionState&gt; { @@ -45,8 +46,6 @@ class SectionBloc extends Bloc&lt;SectionEvent, SectionState&gt; {
45 ///单元列表是否有刷新,有的话返回上一页时通知其刷新接口数据 46 ///单元列表是否有刷新,有的话返回上一页时通知其刷新接口数据
46 bool courseUnitEntityChanged = false; 47 bool courseUnitEntityChanged = false;
47 48
48 - late AudioPlayer audioPlayer; // 点击播放器  
49 - late AudioPlayer backgroundPlayer; // 背景播放器  
50 ///courseUnitId与课程环节列表的映射 49 ///courseUnitId与课程环节列表的映射
51 final Map<int, List<CourseSectionEntity>?> _courseSectionDatasMap = {}; 50 final Map<int, List<CourseSectionEntity>?> _courseSectionDatasMap = {};
52 51
@@ -66,25 +65,12 @@ class SectionBloc extends Bloc&lt;SectionEvent, SectionState&gt; { @@ -66,25 +65,12 @@ class SectionBloc extends Bloc&lt;SectionEvent, SectionState&gt; {
66 on<RequestVideoLessonEvent>(_requestVideoLesson); 65 on<RequestVideoLessonEvent>(_requestVideoLesson);
67 on<CurrentUnitIndexChangeEvent>(_pageControllerChange); 66 on<CurrentUnitIndexChangeEvent>(_pageControllerChange);
68 on<InitEvent>((event, emit) { 67 on<InitEvent>((event, emit) {
69 - audioPlayer = AudioPlayer(playerId: 'section');  
70 - backgroundPlayer = AudioPlayer(playerId: 'back');  
71 - backgroundPlayer.play(AssetSource('count_with_me_instrumental'.assetMp3));  
72 -  
73 - backgroundPlayer.onPlayerStateChanged.listen((event) async {  
74 - if (event == PlayerState.completed) {  
75 - // 播放结束再次播放  
76 - backgroundPlayer  
77 - .play(AssetSource('count_with_me_instrumental'.assetMp3));  
78 - }  
79 - }); 68 + AudioPlayerUtil.getInstance().playAudio(AudioPlayerUtilType.countWithMe);
80 }); 69 });
81 } 70 }
82 @override 71 @override
83 Future<void> close() { 72 Future<void> close() {
84 - audioPlayer.release();  
85 - audioPlayer.dispose();  
86 - backgroundPlayer.release();  
87 - backgroundPlayer.dispose(); 73 + AudioPlayerUtil.getInstance().pause();
88 return super.close(); 74 return super.close();
89 } 75 }
90 76
lib/pages/section/bloc/section_state.dart
@@ -22,5 +22,3 @@ class RequestEnterClassState extends SectionState { @@ -22,5 +22,3 @@ class RequestEnterClassState extends SectionState {
22 } 22 }
23 23
24 class CurrentPageIndexState extends SectionState {} 24 class CurrentPageIndexState extends SectionState {}
25 -  
26 -class VoicePlayChangeState extends SectionState {}  
lib/pages/section/section_page.dart
@@ -12,6 +12,8 @@ import &#39;package:wow_english/pages/section/widgets/section_item.dart&#39;; @@ -12,6 +12,8 @@ import &#39;package:wow_english/pages/section/widgets/section_item.dart&#39;;
12 import 'package:wow_english/pages/section/widgets/section_bouns_item.dart'; 12 import 'package:wow_english/pages/section/widgets/section_bouns_item.dart';
13 import 'package:wow_english/pages/section/widgets/section_header_widget.dart'; 13 import 'package:wow_english/pages/section/widgets/section_header_widget.dart';
14 import 'package:wow_english/route/route.dart'; 14 import 'package:wow_english/route/route.dart';
  15 +import 'package:wow_english/utils/audioplayer_util.dart';
  16 +import 'package:wow_english/utils/log_util.dart';
15 import 'package:wow_english/utils/toast_util.dart'; 17 import 'package:wow_english/utils/toast_util.dart';
16 18
17 import '../../models/course_section_entity.dart'; 19 import '../../models/course_section_entity.dart';
@@ -89,23 +91,23 @@ class _SectionPageView extends StatelessWidget { @@ -89,23 +91,23 @@ class _SectionPageView extends StatelessWidget {
89 currentTime: dataMap['currentTime'], 91 currentTime: dataMap['currentTime'],
90 autoNextSection: dataMap['nextSection'])); 92 autoNextSection: dataMap['nextSection']));
91 } 93 }
92 - if (bloc.backgroundPlayer.state == PlayerState.paused) {  
93 - bloc.backgroundPlayer.resume();  
94 - } 94 + AudioPlayerUtil.getInstance()
  95 + .playAudio(AudioPlayerUtilType.countWithMe);
95 }); 96 });
96 return; 97 return;
97 } 98 }
98 99
99 if (state is RequestEnterClassState) { 100 if (state is RequestEnterClassState) {
100 - bloc.backgroundPlayer.pause();  
101 if (state.courseType != SectionType.practice.value && 101 if (state.courseType != SectionType.practice.value &&
102 state.courseType != SectionType.pictureBook.value) { 102 state.courseType != SectionType.pictureBook.value) {
103 ///视频类型 103 ///视频类型
104 ///获取视频课程内容 104 ///获取视频课程内容
105 if (state.courseType == 1) { 105 if (state.courseType == 1) {
106 - bloc.audioPlayer.play(AssetSource('music_time'.assetMp3)); 106 + AudioPlayerUtil.getInstance()
  107 + .playAudio(AudioPlayerUtilType.musicTime);
107 } else { 108 } else {
108 - bloc.audioPlayer.play(AssetSource('video_time'.assetMp3)); 109 + AudioPlayerUtil.getInstance()
  110 + .playAudio(AudioPlayerUtilType.videoTime);
109 } 111 }
110 Future.delayed(const Duration(seconds: 1), () { 112 Future.delayed(const Duration(seconds: 1), () {
111 bloc.add(RequestVideoLessonEvent( 113 bloc.add(RequestVideoLessonEvent(
@@ -116,7 +118,8 @@ class _SectionPageView extends StatelessWidget { @@ -116,7 +118,8 @@ class _SectionPageView extends StatelessWidget {
116 } 118 }
117 119
118 if (state.courseType == SectionType.pictureBook.value) { 120 if (state.courseType == SectionType.pictureBook.value) {
119 - bloc.audioPlayer.play(AssetSource('reading_time'.assetMp3)); 121 + AudioPlayerUtil.getInstance()
  122 + .playAudio(AudioPlayerUtilType.readingTime);
120 Future.delayed(const Duration(seconds: 1), () { 123 Future.delayed(const Duration(seconds: 1), () {
121 //绘本 124 //绘本
122 pushNamed(AppRouteName.reading, 125 pushNamed(AppRouteName.reading,
@@ -130,9 +133,8 @@ class _SectionPageView extends StatelessWidget { @@ -130,9 +133,8 @@ class _SectionPageView extends StatelessWidget {
130 currentStep: dataMap['currentStep'], 133 currentStep: dataMap['currentStep'],
131 autoNextSection: dataMap['nextSection'], 134 autoNextSection: dataMap['nextSection'],
132 )); 135 ));
133 - if (bloc.backgroundPlayer.state == PlayerState.paused) {  
134 - bloc.backgroundPlayer.resume();  
135 - } 136 + AudioPlayerUtil.getInstance()
  137 + .playAudio(AudioPlayerUtilType.countWithMe);
136 } 138 }
137 }); 139 });
138 }); 140 });
@@ -142,7 +144,8 @@ class _SectionPageView extends StatelessWidget { @@ -142,7 +144,8 @@ class _SectionPageView extends StatelessWidget {
142 144
143 if (state.courseType == SectionType.practice.value) { 145 if (state.courseType == SectionType.practice.value) {
144 //练习 146 //练习
145 - bloc.audioPlayer.play(AssetSource('quiz_time'.assetMp3)); 147 + AudioPlayerUtil.getInstance()
  148 + .playAudio(AudioPlayerUtilType.quizTime);
146 Future.delayed(const Duration(seconds: 1), () { 149 Future.delayed(const Duration(seconds: 1), () {
147 pushNamed(AppRouteName.topicPic, 150 pushNamed(AppRouteName.topicPic,
148 arguments: {'courseLessonId': state.courseLessonId}) 151 arguments: {'courseLessonId': state.courseLessonId})
@@ -154,9 +157,8 @@ class _SectionPageView extends StatelessWidget { @@ -154,9 +157,8 @@ class _SectionPageView extends StatelessWidget {
154 currentStep: dataMap['currentStep'], 157 currentStep: dataMap['currentStep'],
155 autoNextSection: dataMap['nextSection'])); 158 autoNextSection: dataMap['nextSection']));
156 } 159 }
157 - if (bloc.backgroundPlayer.state == PlayerState.paused) {  
158 - bloc.backgroundPlayer.resume();  
159 - } 160 + AudioPlayerUtil.getInstance()
  161 + .playAudio(AudioPlayerUtilType.countWithMe);
160 }); 162 });
161 }); 163 });
162 return; 164 return;
lib/pages/unit/bloc.dart
1 import 'package:bloc/bloc.dart'; 1 import 'package:bloc/bloc.dart';
2 import 'package:wow_english/pages/unit/widget/home_tab_header_widget.dart'; 2 import 'package:wow_english/pages/unit/widget/home_tab_header_widget.dart';
  3 +import 'package:wow_english/utils/audioplayer_util.dart';
3 4
4 import '../../common/request/dao/lesson_dao.dart'; 5 import '../../common/request/dao/lesson_dao.dart';
5 import '../../common/request/exception.dart'; 6 import '../../common/request/exception.dart';
@@ -24,6 +25,9 @@ class UnitBloc extends Bloc&lt;UnitEvent, UnitState&gt; { @@ -24,6 +25,9 @@ class UnitBloc extends Bloc&lt;UnitEvent, UnitState&gt; {
24 25
25 UnitBloc(CourseModuleEntity? courseEntity) : super(UnitState().init()) { 26 UnitBloc(CourseModuleEntity? courseEntity) : super(UnitState().init()) {
26 on<RequestUnitDataEvent>(_requestUnitDatas); 27 on<RequestUnitDataEvent>(_requestUnitDatas);
  28 + on<UnitInitEvent>((event, emit) {
  29 + AudioPlayerUtil.getInstance().playAudio(AudioPlayerUtilType.inMyTummy);
  30 + });
27 } 31 }
28 32
29 void _requestUnitDatas( 33 void _requestUnitDatas(
@@ -45,15 +49,26 @@ class UnitBloc extends Bloc&lt;UnitEvent, UnitState&gt; { @@ -45,15 +49,26 @@ class UnitBloc extends Bloc&lt;UnitEvent, UnitState&gt; {
45 } 49 }
46 50
47 void headerActionEvent(HeaderActionType type) { 51 void headerActionEvent(HeaderActionType type) {
  52 + AudioPlayerUtil.getInstance().pause();
48 if (type == HeaderActionType.video) { 53 if (type == HeaderActionType.video) {
49 pushNamed(AppRouteName.reAfter); 54 pushNamed(AppRouteName.reAfter);
50 } else if (type == HeaderActionType.phase) { 55 } else if (type == HeaderActionType.phase) {
51 - pushNamed(AppRouteName.courseModule); 56 + pushNamed(AppRouteName.courseModule).then((value) => {
  57 + AudioPlayerUtil.getInstance()
  58 + .playAudio(AudioPlayerUtilType.inMyTummy)
  59 + });
  60 + ;
52 } else if (type == HeaderActionType.listen) { 61 } else if (type == HeaderActionType.listen) {
53 - pushNamed(AppRouteName.listen); 62 + pushNamed(AppRouteName.listen).then((value) => {
  63 + AudioPlayerUtil.getInstance()
  64 + .playAudio(AudioPlayerUtilType.inMyTummy)
  65 + });
54 } else if (type == HeaderActionType.shop) { 66 } else if (type == HeaderActionType.shop) {
55 - pushNamed(AppRouteName.shop)  
56 - .then((value) => {exchangeResult = value['exchange']}); 67 + pushNamed(AppRouteName.shop).then((value) => {
  68 + AudioPlayerUtil.getInstance()
  69 + .playAudio(AudioPlayerUtilType.inMyTummy),
  70 + exchangeResult = value['exchange']
  71 + });
57 } else if (type == HeaderActionType.user) { 72 } else if (type == HeaderActionType.user) {
58 pushNamed(AppRouteName.user); 73 pushNamed(AppRouteName.user);
59 } 74 }
lib/pages/unit/event.dart
@@ -6,3 +6,5 @@ class RequestUnitDataEvent extends UnitEvent { @@ -6,3 +6,5 @@ class RequestUnitDataEvent extends UnitEvent {
6 6
7 RequestUnitDataEvent(this.moduleId); 7 RequestUnitDataEvent(this.moduleId);
8 } 8 }
  9 +
  10 +class UnitInitEvent extends UnitEvent {}
lib/pages/unit/view.dart
@@ -5,6 +5,7 @@ import &#39;package:wow_english/pages/unit/state.dart&#39;; @@ -5,6 +5,7 @@ import &#39;package:wow_english/pages/unit/state.dart&#39;;
5 import 'package:wow_english/pages/unit/widget/course_unit_item.dart'; 5 import 'package:wow_english/pages/unit/widget/course_unit_item.dart';
6 import 'package:wow_english/pages/unit/widget/home_tab_header_widget.dart'; 6 import 'package:wow_english/pages/unit/widget/home_tab_header_widget.dart';
7 import 'package:wow_english/route/route.dart'; 7 import 'package:wow_english/route/route.dart';
  8 +import 'package:wow_english/utils/audioplayer_util.dart';
8 9
9 import '../../models/course_module_entity.dart'; 10 import '../../models/course_module_entity.dart';
10 import '../../models/course_unit_entity.dart'; 11 import '../../models/course_unit_entity.dart';
@@ -23,6 +24,7 @@ class UnitPage extends StatelessWidget { @@ -23,6 +24,7 @@ class UnitPage extends StatelessWidget {
23 Widget build(BuildContext context) { 24 Widget build(BuildContext context) {
24 return BlocProvider( 25 return BlocProvider(
25 create: (BuildContext context) => UnitBloc(courseModuleEntity) 26 create: (BuildContext context) => UnitBloc(courseModuleEntity)
  27 + ..add(UnitInitEvent())
26 ..add(RequestUnitDataEvent(courseModuleEntity?.id)), 28 ..add(RequestUnitDataEvent(courseModuleEntity?.id)),
27 child: Builder(builder: (context) => _buildPage(context)), 29 child: Builder(builder: (context) => _buildPage(context)),
28 ); 30 );
@@ -41,6 +43,8 @@ class UnitPage extends StatelessWidget { @@ -41,6 +43,8 @@ class UnitPage extends StatelessWidget {
41 HomeTabHeaderWidget( 43 HomeTabHeaderWidget(
42 courseModuleCode: bloc.getCourseModuleCode(), 44 courseModuleCode: bloc.getCourseModuleCode(),
43 onBack: () { 45 onBack: () {
  46 + AudioPlayerUtil.getInstance()
  47 + .playAudio(AudioPlayerUtilType.touch);
44 popPage(data: {'exchange': bloc.exchangeResult}); 48 popPage(data: {'exchange': bloc.exchangeResult});
45 }, 49 },
46 actionTap: (HeaderActionType type) { 50 actionTap: (HeaderActionType type) {
@@ -63,12 +67,14 @@ class UnitPage extends StatelessWidget { @@ -63,12 +67,14 @@ class UnitPage extends StatelessWidget {
63 showToast('当前单元课程暂未解锁'); 67 showToast('当前单元课程暂未解锁');
64 return; 68 return;
65 } 69 }
66 - 70 + AudioPlayerUtil.getInstance().pause();
67 pushNamed(AppRouteName.courseSection, 71 pushNamed(AppRouteName.courseSection,
68 arguments: { 72 arguments: {
69 'courseUnitEntity': bloc.unitData, 73 'courseUnitEntity': bloc.unitData,
70 'courseUnitId': data.id 74 'courseUnitId': data.id
71 }).then((value) { 75 }).then((value) {
  76 + AudioPlayerUtil.getInstance()
  77 + .playAudio(AudioPlayerUtilType.inMyTummy);
72 if (value != null) { 78 if (value != null) {
73 Map<String, dynamic> dataMap = 79 Map<String, dynamic> dataMap =
74 value as Map<String, dynamic>; 80 value as Map<String, dynamic>;
lib/utils/audioplayer_util.dart 0 → 100644
  1 +import 'package:audioplayers/audioplayers.dart';
  2 +import 'package:wow_english/common/extension/string_extension.dart';
  3 +
  4 +enum AudioPlayerUtilType {
  5 + welcomeToWow('welcome_to_wow'),
  6 + classTime('class_time'),
  7 + gameTime('game_time'),
  8 + musicTime('music_time'),
  9 + readingTime('reading_time'),
  10 + videoTime('video_time'),
  11 + quizTime('quiz_time'),
  12 + countWithMe('count_with_me_instrumental'),
  13 + inMyTummy('in_my_tummy_instrumental'),
  14 + touch('touch_instrumental');
  15 +
  16 + const AudioPlayerUtilType(this.path);
  17 +
  18 + final String path;
  19 +}
  20 +
  21 +class AudioPlayerUtil {
  22 + static AudioPlayerUtil? _instance;
  23 + late AudioPlayer audioPlayer;
  24 + late AudioPlayerUtilType currentType;
  25 +
  26 + // 私有构造函数
  27 + AudioPlayerUtil._internal() {
  28 + audioPlayer = AudioPlayer();
  29 + audioPlayer.onPlayerStateChanged.listen((event) async {
  30 + if (event == PlayerState.completed) {
  31 + // 播放结束再次播放
  32 + if (currentType == AudioPlayerUtilType.inMyTummy) {
  33 + AudioPlayerUtil.getInstance()
  34 + .playAudio(AudioPlayerUtilType.inMyTummy);
  35 + }
  36 + if (currentType == AudioPlayerUtilType.countWithMe) {
  37 + AudioPlayerUtil.getInstance()
  38 + .playAudio(AudioPlayerUtilType.countWithMe);
  39 + }
  40 + if (currentType == AudioPlayerUtilType.welcomeToWow) {
  41 + AudioPlayerUtil.getInstance().playAudio(AudioPlayerUtilType.touch);
  42 + }
  43 + if (currentType == AudioPlayerUtilType.touch) {
  44 + AudioPlayerUtil.getInstance().playAudio(AudioPlayerUtilType.touch);
  45 + }
  46 + }
  47 + });
  48 + }
  49 +
  50 + static AudioPlayerUtil getInstance() {
  51 + _instance ??= AudioPlayerUtil._internal();
  52 + return _instance!;
  53 + }
  54 +
  55 +// 播放音频
  56 + Future<void> playAudio(AudioPlayerUtilType type) async {
  57 + currentType = type;
  58 + String path = type.path;
  59 + await audioPlayer.play(AssetSource(path.assetMp3), volume: 0.5);
  60 + await audioPlayer.onPlayerComplete.first;
  61 + }
  62 +
  63 + // stop
  64 + void stop() {
  65 + audioPlayer.stop();
  66 + }
  67 +
  68 + // pause
  69 + void pause() {
  70 + if (audioPlayer.state == PlayerState.playing) {
  71 + audioPlayer.pause();
  72 + }
  73 + }
  74 +
  75 + // resume
  76 + void resume() {
  77 + if (audioPlayer.state == PlayerState.paused) {
  78 + audioPlayer.resume();
  79 + }
  80 + }
  81 +}