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 | 44 | return; |
45 | 45 | } |
46 | 46 | Log.d( |
47 | - "WQF _checkUpdate appVersionEntity: $appVersionEntity localVersion=$localVersion"); | |
47 | + "HomeBloc _checkUpdate appVersionEntity: $appVersionEntity localVersion=$localVersion"); | |
48 | 48 | if (localVersion < int.parse(appVersionEntity.version ?? '0')) { |
49 | 49 | emit(UpdateDialogState( |
50 | 50 | appVersionEntity.volType == UpdateStrategy.FORCE.name, | ... | ... |
lib/pages/home/view.dart
... | ... | @@ -60,8 +60,8 @@ class _HomePageView extends StatelessWidget { |
60 | 60 | child: Column( |
61 | 61 | children: [ |
62 | 62 | BaseHomeHeaderWidget( |
63 | - callBack: (value) => { | |
64 | - AudioPlayerUtil.getInstance() | |
63 | + callBack: (value) async => { | |
64 | + await AudioPlayerUtil.getInstance() | |
65 | 65 | .playAudio(AudioPlayerUtilType.touch), |
66 | 66 | bloc.exchangeResult = value['exchange'], |
67 | 67 | bloc.add(ExchangeSuccessEvent()) |
... | ... | @@ -113,15 +113,15 @@ class _HomePageView extends StatelessWidget { |
113 | 113 | builder: (context, userState) { |
114 | 114 | return GestureDetector( |
115 | 115 | onTap: () { |
116 | - _checkPermission(() { | |
117 | - AudioPlayerUtil.getInstance().pause(); | |
116 | + _checkPermission(() async { | |
117 | + await AudioPlayerUtil.getInstance().pause(); | |
118 | 118 | Navigator.of(context).pushNamed( |
119 | 119 | AppRouteName.webView, |
120 | 120 | arguments: { |
121 | 121 | 'urlStr': AppConsts.xiaoeShopUrl, |
122 | 122 | 'webViewTitle': 'Wow精选' |
123 | - }).then((value) => { | |
124 | - AudioPlayerUtil.getInstance().playAudio( | |
123 | + }).then((value) async => { | |
124 | + await AudioPlayerUtil.getInstance().playAudio( | |
125 | 125 | AudioPlayerUtilType.touch), |
126 | 126 | }); |
127 | 127 | }, bloc); | ... | ... |
lib/pages/home/widgets/BaseHomeHeaderWidget.dart
... | ... | @@ -84,8 +84,8 @@ class BaseHomeHeaderWidget extends StatelessWidget { |
84 | 84 | offstage: AppConfigHelper.shouldHidePay() || |
85 | 85 | !UserUtil.isLogined(), |
86 | 86 | child: GestureDetector( |
87 | - onTap: () => { | |
88 | - AudioPlayerUtil.getInstance().pause(), | |
87 | + onTap: () async => { | |
88 | + await AudioPlayerUtil.getInstance().pause(), | |
89 | 89 | pushNamed(AppRouteName.shop).then((value) { |
90 | 90 | if (value != null) { |
91 | 91 | if (callBack == null) { |
... | ... | @@ -115,9 +115,9 @@ class BaseHomeHeaderWidget extends StatelessWidget { |
115 | 115 | ); |
116 | 116 | } |
117 | 117 | |
118 | - void onUserClick() { | |
118 | + Future<void> onUserClick() async { | |
119 | 119 | if (UserUtil.isLogined()) { |
120 | - AudioPlayerUtil.getInstance().pause(); | |
120 | + await AudioPlayerUtil.getInstance().pause(); | |
121 | 121 | pushNamed(AppRouteName.user).then((value) { |
122 | 122 | if (value != null) { |
123 | 123 | if (callBack == null) { | ... | ... |
lib/pages/section/bloc/section_bloc.dart
... | ... | @@ -64,15 +64,10 @@ class SectionBloc extends Bloc<SectionEvent, SectionState> { |
64 | 64 | on<RequestEnterClassEvent>(_requestEnterClass); |
65 | 65 | on<RequestVideoLessonEvent>(_requestVideoLesson); |
66 | 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 | 72 | void _requestSectionsData( |
78 | 73 | RequestDataEvent event, Emitter<SectionState> emitter) async { | ... | ... |
lib/pages/unit/bloc.dart
... | ... | @@ -48,9 +48,10 @@ class UnitBloc extends Bloc<UnitEvent, UnitState> { |
48 | 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 | 53 | if (type == HeaderActionType.video) { |
54 | + //视频跟读暂时隐藏了 | |
54 | 55 | pushNamed(AppRouteName.reAfter); |
55 | 56 | } else if (type == HeaderActionType.phase) { |
56 | 57 | pushNamed(AppRouteName.courseModule).then((value) => { | ... | ... |
lib/pages/unit/view.dart
... | ... | @@ -62,12 +62,12 @@ class UnitPage extends StatelessWidget { |
62 | 62 | CourseUnitDetail? data = |
63 | 63 | bloc.unitData?.courseUnitVOList?[index]; |
64 | 64 | return GestureDetector( |
65 | - onTap: () { | |
65 | + onTap: () async { | |
66 | 66 | if (data.lock == true) { |
67 | 67 | showToast('当前单元课程暂未解锁'); |
68 | 68 | return; |
69 | 69 | } |
70 | - AudioPlayerUtil.getInstance().pause(); | |
70 | + // await AudioPlayerUtil.getInstance().pause(); | |
71 | 71 | pushNamed(AppRouteName.courseSection, |
72 | 72 | arguments: { |
73 | 73 | 'courseUnitEntity': bloc.unitData, | ... | ... |
lib/pages/user/setting/reback_page.dart
... | ... | @@ -26,73 +26,87 @@ class ReBackPageState extends State<ReBackPage> { |
26 | 26 | @override |
27 | 27 | Widget build(BuildContext context) { |
28 | 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 | 112 | \ No newline at end of file |
113 | +} | ... | ... |
lib/utils/audio_player_util.dart
... | ... | @@ -2,6 +2,8 @@ import 'package:audioplayers/audioplayers.dart'; |
2 | 2 | import 'package:flutter/cupertino.dart'; |
3 | 3 | import 'package:wow_english/common/extension/string_extension.dart'; |
4 | 4 | |
5 | +import 'log_util.dart'; | |
6 | + | |
5 | 7 | enum AudioPlayerUtilType { |
6 | 8 | welcomeToWow('welcome_to_wow'), |
7 | 9 | classTime('class_time'), |
... | ... | @@ -24,6 +26,7 @@ class AudioPlayerUtil extends WidgetsBindingObserver { |
24 | 26 | late AudioPlayer _audioPlayer; |
25 | 27 | late AudioPlayerUtilType currentType; |
26 | 28 | bool _wasPlaying = false; |
29 | + static const TAG = "AudioPlayerUtil"; | |
27 | 30 | |
28 | 31 | // 私有构造函数 |
29 | 32 | AudioPlayerUtil._internal() { |
... | ... | @@ -58,6 +61,7 @@ class AudioPlayerUtil extends WidgetsBindingObserver { |
58 | 61 | |
59 | 62 | // 播放音频 |
60 | 63 | Future<void> playAudio(AudioPlayerUtilType type) async { |
64 | + Log.d("$TAG playAudio $type"); | |
61 | 65 | currentType = type; |
62 | 66 | String path = type.path; |
63 | 67 | await _audioPlayer.play(AssetSource(path.assetMp3), volume: 0.5); |
... | ... | @@ -66,11 +70,13 @@ class AudioPlayerUtil extends WidgetsBindingObserver { |
66 | 70 | |
67 | 71 | // stop |
68 | 72 | Future<void> stop() async { |
73 | + Log.d("$TAG stop _audioPlayer.state=${_audioPlayer.state}"); | |
69 | 74 | await _audioPlayer.stop(); |
70 | 75 | } |
71 | 76 | |
72 | 77 | // pause |
73 | 78 | Future<void> pause() async { |
79 | + Log.d("$TAG pause _audioPlayer.state=${_audioPlayer.state}"); | |
74 | 80 | if (_audioPlayer.state == PlayerState.playing) { |
75 | 81 | await _audioPlayer.pause(); |
76 | 82 | } |
... | ... | @@ -78,6 +84,7 @@ class AudioPlayerUtil extends WidgetsBindingObserver { |
78 | 84 | |
79 | 85 | // resume |
80 | 86 | Future<void> resume() async { |
87 | + Log.d("$TAG resume _audioPlayer.state=${_audioPlayer.state}"); | |
81 | 88 | if (_audioPlayer.state == PlayerState.paused) { |
82 | 89 | await _audioPlayer.resume(); |
83 | 90 | } |
... | ... | @@ -85,6 +92,7 @@ class AudioPlayerUtil extends WidgetsBindingObserver { |
85 | 92 | |
86 | 93 | @override |
87 | 94 | void didChangeAppLifecycleState(AppLifecycleState state) async { |
95 | + Log.d("$TAG didChangeAppLifecycleState appState=$state _wasPlaying=$_wasPlaying _audioPlayer.state=${_audioPlayer.state}"); | |
88 | 96 | if (state == AppLifecycleState.paused) { |
89 | 97 | if (_audioPlayer.state == PlayerState.playing) { |
90 | 98 | _wasPlaying = true; |
... | ... | @@ -99,6 +107,7 @@ class AudioPlayerUtil extends WidgetsBindingObserver { |
99 | 107 | } |
100 | 108 | |
101 | 109 | void dispose() { |
110 | + Log.d("$TAG dispose _audioPlayer.state=${_audioPlayer.state}"); | |
102 | 111 | _audioPlayer.dispose(); |
103 | 112 | WidgetsBinding.instance.removeObserver(this); |
104 | 113 | } | ... | ... |