Commit 2d1ead5369e419d9e972ead8b9373a0ba058d276
1 parent
9e29ffea
feat:背景音播放优化
Showing
8 changed files
with
104 additions
and
85 deletions
lib/pages/home/bloc.dart
@@ -44,7 +44,7 @@ class HomeBloc extends Bloc<HomeEvent, HomeState> { | @@ -44,7 +44,7 @@ class HomeBloc extends Bloc<HomeEvent, HomeState> { | ||
44 | return; | 44 | return; |
45 | } | 45 | } |
46 | Log.d( | 46 | Log.d( |
47 | - "WQF _checkUpdate appVersionEntity: $appVersionEntity localVersion=$localVersion"); | 47 | + "HomeBloc _checkUpdate appVersionEntity: $appVersionEntity localVersion=$localVersion"); |
48 | if (localVersion < int.parse(appVersionEntity.version ?? '0')) { | 48 | if (localVersion < int.parse(appVersionEntity.version ?? '0')) { |
49 | emit(UpdateDialogState( | 49 | emit(UpdateDialogState( |
50 | appVersionEntity.volType == UpdateStrategy.FORCE.name, | 50 | appVersionEntity.volType == UpdateStrategy.FORCE.name, |
lib/pages/home/view.dart
@@ -60,8 +60,8 @@ class _HomePageView extends StatelessWidget { | @@ -60,8 +60,8 @@ class _HomePageView extends StatelessWidget { | ||
60 | child: Column( | 60 | child: Column( |
61 | children: [ | 61 | children: [ |
62 | BaseHomeHeaderWidget( | 62 | BaseHomeHeaderWidget( |
63 | - callBack: (value) => { | ||
64 | - AudioPlayerUtil.getInstance() | 63 | + callBack: (value) async => { |
64 | + await AudioPlayerUtil.getInstance() | ||
65 | .playAudio(AudioPlayerUtilType.touch), | 65 | .playAudio(AudioPlayerUtilType.touch), |
66 | bloc.exchangeResult = value['exchange'], | 66 | bloc.exchangeResult = value['exchange'], |
67 | bloc.add(ExchangeSuccessEvent()) | 67 | bloc.add(ExchangeSuccessEvent()) |
@@ -113,15 +113,15 @@ class _HomePageView extends StatelessWidget { | @@ -113,15 +113,15 @@ class _HomePageView extends StatelessWidget { | ||
113 | builder: (context, userState) { | 113 | builder: (context, userState) { |
114 | return GestureDetector( | 114 | return GestureDetector( |
115 | onTap: () { | 115 | onTap: () { |
116 | - _checkPermission(() { | ||
117 | - AudioPlayerUtil.getInstance().pause(); | 116 | + _checkPermission(() async { |
117 | + await AudioPlayerUtil.getInstance().pause(); | ||
118 | Navigator.of(context).pushNamed( | 118 | Navigator.of(context).pushNamed( |
119 | AppRouteName.webView, | 119 | AppRouteName.webView, |
120 | arguments: { | 120 | arguments: { |
121 | 'urlStr': AppConsts.xiaoeShopUrl, | 121 | 'urlStr': AppConsts.xiaoeShopUrl, |
122 | 'webViewTitle': 'Wow精选' | 122 | 'webViewTitle': 'Wow精选' |
123 | - }).then((value) => { | ||
124 | - AudioPlayerUtil.getInstance().playAudio( | 123 | + }).then((value) async => { |
124 | + await AudioPlayerUtil.getInstance().playAudio( | ||
125 | AudioPlayerUtilType.touch), | 125 | AudioPlayerUtilType.touch), |
126 | }); | 126 | }); |
127 | }, bloc); | 127 | }, bloc); |
lib/pages/home/widgets/BaseHomeHeaderWidget.dart
@@ -84,8 +84,8 @@ class BaseHomeHeaderWidget extends StatelessWidget { | @@ -84,8 +84,8 @@ class BaseHomeHeaderWidget extends StatelessWidget { | ||
84 | offstage: AppConfigHelper.shouldHidePay() || | 84 | offstage: AppConfigHelper.shouldHidePay() || |
85 | !UserUtil.isLogined(), | 85 | !UserUtil.isLogined(), |
86 | child: GestureDetector( | 86 | child: GestureDetector( |
87 | - onTap: () => { | ||
88 | - AudioPlayerUtil.getInstance().pause(), | 87 | + onTap: () async => { |
88 | + await AudioPlayerUtil.getInstance().pause(), | ||
89 | pushNamed(AppRouteName.shop).then((value) { | 89 | pushNamed(AppRouteName.shop).then((value) { |
90 | if (value != null) { | 90 | if (value != null) { |
91 | if (callBack == null) { | 91 | if (callBack == null) { |
@@ -115,9 +115,9 @@ class BaseHomeHeaderWidget extends StatelessWidget { | @@ -115,9 +115,9 @@ class BaseHomeHeaderWidget extends StatelessWidget { | ||
115 | ); | 115 | ); |
116 | } | 116 | } |
117 | 117 | ||
118 | - void onUserClick() { | 118 | + Future<void> onUserClick() async { |
119 | if (UserUtil.isLogined()) { | 119 | if (UserUtil.isLogined()) { |
120 | - AudioPlayerUtil.getInstance().pause(); | 120 | + await AudioPlayerUtil.getInstance().pause(); |
121 | pushNamed(AppRouteName.user).then((value) { | 121 | pushNamed(AppRouteName.user).then((value) { |
122 | if (value != null) { | 122 | if (value != null) { |
123 | if (callBack == null) { | 123 | if (callBack == null) { |
lib/pages/section/bloc/section_bloc.dart
@@ -64,15 +64,10 @@ class SectionBloc extends Bloc<SectionEvent, SectionState> { | @@ -64,15 +64,10 @@ class SectionBloc extends Bloc<SectionEvent, SectionState> { | ||
64 | on<RequestEnterClassEvent>(_requestEnterClass); | 64 | on<RequestEnterClassEvent>(_requestEnterClass); |
65 | on<RequestVideoLessonEvent>(_requestVideoLesson); | 65 | on<RequestVideoLessonEvent>(_requestVideoLesson); |
66 | on<CurrentUnitIndexChangeEvent>(_pageControllerChange); | 66 | on<CurrentUnitIndexChangeEvent>(_pageControllerChange); |
67 | - on<InitEvent>((event, emit) { | ||
68 | - AudioPlayerUtil.getInstance().playAudio(AudioPlayerUtilType.countWithMe); | 67 | + on<InitEvent>((event, emit) async { |
68 | + await AudioPlayerUtil.getInstance().playAudio(AudioPlayerUtilType.countWithMe); | ||
69 | }); | 69 | }); |
70 | } | 70 | } |
71 | - @override | ||
72 | - Future<void> close() { | ||
73 | - AudioPlayerUtil.getInstance().pause(); | ||
74 | - return super.close(); | ||
75 | - } | ||
76 | 71 | ||
77 | void _requestSectionsData( | 72 | void _requestSectionsData( |
78 | RequestDataEvent event, Emitter<SectionState> emitter) async { | 73 | RequestDataEvent event, Emitter<SectionState> emitter) async { |
lib/pages/unit/bloc.dart
@@ -48,9 +48,10 @@ class UnitBloc extends Bloc<UnitEvent, UnitState> { | @@ -48,9 +48,10 @@ class UnitBloc extends Bloc<UnitEvent, UnitState> { | ||
48 | return _moduleEntity?.code ?? _unitData?.courseModuleCode; | 48 | return _moduleEntity?.code ?? _unitData?.courseModuleCode; |
49 | } | 49 | } |
50 | 50 | ||
51 | - void headerActionEvent(HeaderActionType type) { | ||
52 | - AudioPlayerUtil.getInstance().pause(); | 51 | + Future<void> headerActionEvent(HeaderActionType type) async { |
52 | + await AudioPlayerUtil.getInstance().pause(); | ||
53 | if (type == HeaderActionType.video) { | 53 | if (type == HeaderActionType.video) { |
54 | + //视频跟读暂时隐藏了 | ||
54 | pushNamed(AppRouteName.reAfter); | 55 | pushNamed(AppRouteName.reAfter); |
55 | } else if (type == HeaderActionType.phase) { | 56 | } else if (type == HeaderActionType.phase) { |
56 | pushNamed(AppRouteName.courseModule).then((value) => { | 57 | pushNamed(AppRouteName.courseModule).then((value) => { |
lib/pages/unit/view.dart
@@ -62,12 +62,12 @@ class UnitPage extends StatelessWidget { | @@ -62,12 +62,12 @@ class UnitPage extends StatelessWidget { | ||
62 | CourseUnitDetail? data = | 62 | CourseUnitDetail? data = |
63 | bloc.unitData?.courseUnitVOList?[index]; | 63 | bloc.unitData?.courseUnitVOList?[index]; |
64 | return GestureDetector( | 64 | return GestureDetector( |
65 | - onTap: () { | 65 | + onTap: () async { |
66 | if (data.lock == true) { | 66 | if (data.lock == true) { |
67 | showToast('当前单元课程暂未解锁'); | 67 | showToast('当前单元课程暂未解锁'); |
68 | return; | 68 | return; |
69 | } | 69 | } |
70 | - AudioPlayerUtil.getInstance().pause(); | 70 | + // await AudioPlayerUtil.getInstance().pause(); |
71 | pushNamed(AppRouteName.courseSection, | 71 | pushNamed(AppRouteName.courseSection, |
72 | arguments: { | 72 | arguments: { |
73 | 'courseUnitEntity': bloc.unitData, | 73 | 'courseUnitEntity': bloc.unitData, |
lib/pages/user/setting/reback_page.dart
@@ -26,73 +26,87 @@ class ReBackPageState extends State<ReBackPage> { | @@ -26,73 +26,87 @@ class ReBackPageState extends State<ReBackPage> { | ||
26 | @override | 26 | @override |
27 | Widget build(BuildContext context) { | 27 | Widget build(BuildContext context) { |
28 | return Scaffold( | 28 | return Scaffold( |
29 | - appBar: const WEAppBar( | ||
30 | - titleText: '我要反馈', | ||
31 | - ), | ||
32 | - body: Container( | ||
33 | - color: Colors.white, | ||
34 | - padding: EdgeInsets.symmetric( | ||
35 | - horizontal: 24.w | 29 | + appBar: const WEAppBar( |
30 | + titleText: '我要反馈', | ||
36 | ), | 31 | ), |
37 | - child: SafeArea( | ||
38 | - child: Column( | ||
39 | - children: [ | ||
40 | - 20.verticalSpace, | ||
41 | - Row( | ||
42 | - mainAxisAlignment: MainAxisAlignment.spaceBetween, | ||
43 | - children: [ | ||
44 | - Text( | ||
45 | - '请输入您要反馈的问题和意见,10-500个字', | ||
46 | - textAlign: TextAlign.left, | ||
47 | - style: TextStyle( | ||
48 | - fontSize: 19.sp, | ||
49 | - color: HexColor('#333333') | ||
50 | - ), | ||
51 | - ), | ||
52 | - Text( | ||
53 | - '48/500', | ||
54 | - textAlign: TextAlign.right, | ||
55 | - style: TextStyle( | ||
56 | - fontSize: 19.sp, | ||
57 | - color: HexColor('#333333') | ||
58 | - ),) | ||
59 | - ], | ||
60 | - ), | ||
61 | - 9.5.verticalSpace, | ||
62 | - Expanded( | ||
63 | - child: Container( | ||
64 | - decoration: BoxDecoration( | ||
65 | - image: DecorationImage( | ||
66 | - fit: BoxFit.fill, | ||
67 | - image: AssetImage('bg_reback'.assetPng) | 32 | + body: Container( |
33 | + color: Colors.white, | ||
34 | + padding: EdgeInsets.symmetric(horizontal: 10.w), | ||
35 | + child: SafeArea( | ||
36 | + child: LayoutBuilder(builder: (context, constraints) { | ||
37 | + return SingleChildScrollView( | ||
38 | + child: ConstrainedBox( | ||
39 | + constraints: BoxConstraints( | ||
40 | + minHeight: constraints.maxHeight, | ||
41 | + ), | ||
42 | + child: IntrinsicHeight( | ||
43 | + child: Column( | ||
44 | + children: [ | ||
45 | + 20.verticalSpace, | ||
46 | + Row( | ||
47 | + mainAxisAlignment: MainAxisAlignment.spaceBetween, | ||
48 | + children: [ | ||
49 | + Text( | ||
50 | + '请输入您要反馈的问题和意见,10-500个字', | ||
51 | + textAlign: TextAlign.left, | ||
52 | + style: TextStyle( | ||
53 | + fontSize: 19.sp, color: HexColor('#333333')), | ||
54 | + ), | ||
55 | + Text( | ||
56 | + '48/500', | ||
57 | + textAlign: TextAlign.right, | ||
58 | + style: TextStyle( | ||
59 | + fontSize: 19.sp, color: HexColor('#333333')), | ||
60 | + ) | ||
61 | + ], | ||
62 | + ), | ||
63 | + 9.5.verticalSpace, | ||
64 | + Expanded( | ||
65 | + child: Container( | ||
66 | + decoration: BoxDecoration( | ||
67 | + image: DecorationImage( | ||
68 | + image: AssetImage('bg_reback'.assetPng), | ||
69 | + fit: BoxFit.fill)), | ||
70 | + child: Padding( | ||
71 | + padding: const EdgeInsets.symmetric( | ||
72 | + vertical: 10, horizontal: 16), | ||
73 | + // 设置对称内边距 | ||
74 | + child: TextField( | ||
75 | + textInputAction: TextInputAction.done, | ||
76 | + decoration: InputDecoration( | ||
77 | + border: InputBorder.none, | ||
78 | + hintStyle: TextStyle( | ||
79 | + fontSize: 16.sp, | ||
80 | + color: const Color(0xFF999999))), | ||
81 | + ), | ||
82 | + ), | ||
83 | + ), | ||
84 | + ), | ||
85 | + 4.5.verticalSpace, | ||
86 | + Container( | ||
87 | + decoration: BoxDecoration( | ||
88 | + image: DecorationImage( | ||
89 | + fit: BoxFit.fill, | ||
90 | + image: AssetImage(_canEnsure | ||
91 | + ? 're_button'.assetPng | ||
92 | + : 're_button_dis'.assetPng))), | ||
93 | + alignment: Alignment.center, | ||
94 | + width: 91.w, | ||
95 | + height: 45.h, | ||
96 | + child: Text( | ||
97 | + '提交', | ||
98 | + textAlign: TextAlign.center, | ||
99 | + style: | ||
100 | + TextStyle(color: Colors.white, fontSize: 17.sp), | ||
101 | + ), | ||
68 | ) | 102 | ) |
103 | + ], | ||
69 | ), | 104 | ), |
70 | ), | 105 | ), |
71 | ), | 106 | ), |
72 | - 4.5.verticalSpace, | ||
73 | - Container( | ||
74 | - decoration: BoxDecoration( | ||
75 | - image: DecorationImage( | ||
76 | - fit: BoxFit.fill, | ||
77 | - image: AssetImage(_canEnsure?'re_button'.assetPng:'re_button_dis'.assetPng) | ||
78 | - ) | ||
79 | - ), | ||
80 | - alignment: Alignment.center, | ||
81 | - width: 91.w, | ||
82 | - height: 45.h, | ||
83 | - child: Text( | ||
84 | - '提交', | ||
85 | - textAlign: TextAlign.center, | ||
86 | - style: TextStyle( | ||
87 | - color: Colors.white, | ||
88 | - fontSize: 17.sp | ||
89 | - ), | ||
90 | - ), | ||
91 | - ) | ||
92 | - ], | ||
93 | - ), | 107 | + ); |
108 | + }), | ||
94 | ), | 109 | ), |
95 | - ) | ||
96 | - ); | 110 | + )); |
97 | } | 111 | } |
98 | -} | ||
99 | \ No newline at end of file | 112 | \ No newline at end of file |
113 | +} |
lib/utils/audio_player_util.dart
@@ -2,6 +2,8 @@ import 'package:audioplayers/audioplayers.dart'; | @@ -2,6 +2,8 @@ import 'package:audioplayers/audioplayers.dart'; | ||
2 | import 'package:flutter/cupertino.dart'; | 2 | import 'package:flutter/cupertino.dart'; |
3 | import 'package:wow_english/common/extension/string_extension.dart'; | 3 | import 'package:wow_english/common/extension/string_extension.dart'; |
4 | 4 | ||
5 | +import 'log_util.dart'; | ||
6 | + | ||
5 | enum AudioPlayerUtilType { | 7 | enum AudioPlayerUtilType { |
6 | welcomeToWow('welcome_to_wow'), | 8 | welcomeToWow('welcome_to_wow'), |
7 | classTime('class_time'), | 9 | classTime('class_time'), |
@@ -24,6 +26,7 @@ class AudioPlayerUtil extends WidgetsBindingObserver { | @@ -24,6 +26,7 @@ class AudioPlayerUtil extends WidgetsBindingObserver { | ||
24 | late AudioPlayer _audioPlayer; | 26 | late AudioPlayer _audioPlayer; |
25 | late AudioPlayerUtilType currentType; | 27 | late AudioPlayerUtilType currentType; |
26 | bool _wasPlaying = false; | 28 | bool _wasPlaying = false; |
29 | + static const TAG = "AudioPlayerUtil"; | ||
27 | 30 | ||
28 | // 私有构造函数 | 31 | // 私有构造函数 |
29 | AudioPlayerUtil._internal() { | 32 | AudioPlayerUtil._internal() { |
@@ -58,6 +61,7 @@ class AudioPlayerUtil extends WidgetsBindingObserver { | @@ -58,6 +61,7 @@ class AudioPlayerUtil extends WidgetsBindingObserver { | ||
58 | 61 | ||
59 | // 播放音频 | 62 | // 播放音频 |
60 | Future<void> playAudio(AudioPlayerUtilType type) async { | 63 | Future<void> playAudio(AudioPlayerUtilType type) async { |
64 | + Log.d("$TAG playAudio $type"); | ||
61 | currentType = type; | 65 | currentType = type; |
62 | String path = type.path; | 66 | String path = type.path; |
63 | await _audioPlayer.play(AssetSource(path.assetMp3), volume: 0.5); | 67 | await _audioPlayer.play(AssetSource(path.assetMp3), volume: 0.5); |
@@ -66,11 +70,13 @@ class AudioPlayerUtil extends WidgetsBindingObserver { | @@ -66,11 +70,13 @@ class AudioPlayerUtil extends WidgetsBindingObserver { | ||
66 | 70 | ||
67 | // stop | 71 | // stop |
68 | Future<void> stop() async { | 72 | Future<void> stop() async { |
73 | + Log.d("$TAG stop _audioPlayer.state=${_audioPlayer.state}"); | ||
69 | await _audioPlayer.stop(); | 74 | await _audioPlayer.stop(); |
70 | } | 75 | } |
71 | 76 | ||
72 | // pause | 77 | // pause |
73 | Future<void> pause() async { | 78 | Future<void> pause() async { |
79 | + Log.d("$TAG pause _audioPlayer.state=${_audioPlayer.state}"); | ||
74 | if (_audioPlayer.state == PlayerState.playing) { | 80 | if (_audioPlayer.state == PlayerState.playing) { |
75 | await _audioPlayer.pause(); | 81 | await _audioPlayer.pause(); |
76 | } | 82 | } |
@@ -78,6 +84,7 @@ class AudioPlayerUtil extends WidgetsBindingObserver { | @@ -78,6 +84,7 @@ class AudioPlayerUtil extends WidgetsBindingObserver { | ||
78 | 84 | ||
79 | // resume | 85 | // resume |
80 | Future<void> resume() async { | 86 | Future<void> resume() async { |
87 | + Log.d("$TAG resume _audioPlayer.state=${_audioPlayer.state}"); | ||
81 | if (_audioPlayer.state == PlayerState.paused) { | 88 | if (_audioPlayer.state == PlayerState.paused) { |
82 | await _audioPlayer.resume(); | 89 | await _audioPlayer.resume(); |
83 | } | 90 | } |
@@ -85,6 +92,7 @@ class AudioPlayerUtil extends WidgetsBindingObserver { | @@ -85,6 +92,7 @@ class AudioPlayerUtil extends WidgetsBindingObserver { | ||
85 | 92 | ||
86 | @override | 93 | @override |
87 | void didChangeAppLifecycleState(AppLifecycleState state) async { | 94 | void didChangeAppLifecycleState(AppLifecycleState state) async { |
95 | + Log.d("$TAG didChangeAppLifecycleState appState=$state _wasPlaying=$_wasPlaying _audioPlayer.state=${_audioPlayer.state}"); | ||
88 | if (state == AppLifecycleState.paused) { | 96 | if (state == AppLifecycleState.paused) { |
89 | if (_audioPlayer.state == PlayerState.playing) { | 97 | if (_audioPlayer.state == PlayerState.playing) { |
90 | _wasPlaying = true; | 98 | _wasPlaying = true; |
@@ -99,6 +107,7 @@ class AudioPlayerUtil extends WidgetsBindingObserver { | @@ -99,6 +107,7 @@ class AudioPlayerUtil extends WidgetsBindingObserver { | ||
99 | } | 107 | } |
100 | 108 | ||
101 | void dispose() { | 109 | void dispose() { |
110 | + Log.d("$TAG dispose _audioPlayer.state=${_audioPlayer.state}"); | ||
102 | _audioPlayer.dispose(); | 111 | _audioPlayer.dispose(); |
103 | WidgetsBinding.instance.removeObserver(this); | 112 | WidgetsBinding.instance.removeObserver(this); |
104 | } | 113 | } |