Commit 2d1ead5369e419d9e972ead8b9373a0ba058d276

Authored by 吴启风
1 parent 9e29ffea

feat:背景音播放优化

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&lt;SectionEvent, SectionState&gt; {
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&lt;UnitEvent, UnitState&gt; {
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&lt;ReBackPage&gt; {
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 &#39;package:audioplayers/audioplayers.dart&#39;;
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 }
... ...