Commit b1869cf8c5a103abd2206171c56033fe68ce78c8
1 parent
d5fb5080
背景音乐添加
Showing
11 changed files
with
187 additions
and
77 deletions
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<GamesEvent, GamesState> { | @@ -31,7 +31,7 @@ class GamesBloc extends Bloc<GamesEvent, GamesState> { | ||
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<GamesEvent, GamesState> { | @@ -39,13 +39,16 @@ class GamesBloc extends Bloc<GamesEvent, GamesState> { | ||
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 'package:audioplayers/audioplayers.dart'; | @@ -2,6 +2,7 @@ import 'package:audioplayers/audioplayers.dart'; | ||
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<HomeEvent, HomeState> { | @@ -17,16 +18,10 @@ class HomeBloc extends Bloc<HomeEvent, HomeState> { | ||
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 'package:wow_english/pages/home/state.dart'; | @@ -12,6 +12,7 @@ import 'package:wow_english/pages/home/state.dart'; | ||
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 'package:flutter_bloc/flutter_bloc.dart'; | @@ -3,6 +3,7 @@ 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/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 'package:wow_english/common/request/dao/lesson_dao.dart'; | @@ -9,6 +9,7 @@ import 'package:wow_english/common/request/dao/lesson_dao.dart'; | ||
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<SectionEvent, SectionState> { | @@ -45,8 +46,6 @@ class SectionBloc extends Bloc<SectionEvent, SectionState> { | ||
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<SectionEvent, SectionState> { | @@ -66,25 +65,12 @@ class SectionBloc extends Bloc<SectionEvent, SectionState> { | ||
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 'package:wow_english/pages/section/widgets/section_item.dart'; | @@ -12,6 +12,8 @@ import 'package:wow_english/pages/section/widgets/section_item.dart'; | ||
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<UnitEvent, UnitState> { | @@ -24,6 +25,9 @@ class UnitBloc extends Bloc<UnitEvent, UnitState> { | ||
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<UnitEvent, UnitState> { | @@ -45,15 +49,26 @@ class UnitBloc extends Bloc<UnitEvent, UnitState> { | ||
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
lib/pages/unit/view.dart
@@ -5,6 +5,7 @@ import 'package:wow_english/pages/unit/state.dart'; | @@ -5,6 +5,7 @@ import 'package:wow_english/pages/unit/state.dart'; | ||
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 | +} |