#flutter #dart
#flutter #dart
Вопрос:
В моем приложении Flutter я использую аудиоплееры: ^ 0.17.0 для воспроизведения музыки. Когда я включаю музыку и хочу покинуть страницу, я хочу прекратить воспроизведение музыки. Для этой цели я использую dispose() . И похоже, что это работает. Проблема, с которой я сталкиваюсь, заключается в том, что у меня ошибка в консоли. Я думаю, это потому, что я использую async, но я не уверен, как это исправить. Или, может быть, есть другое решение, которое я могу использовать для этой цели. Есть предложения?
Вот мой код и ошибка:
class _MyAppState extends State<HomeApp> {
var currentPageValue = 0;
double currentPage = 0;
PageController pageController = PageController(initialPage: 0);
AudioPlayer audioPlayer = new AudioPlayer();
@override
void initState() {
super.initState();
pageController.addListener(() {
if (pageController.page == pageController.page.roundToDouble()) {
setState(() {
currentPage = pageController.page;
});
}
});
}
bool playing = false;
@override
Future<void> dispose() async {
await audioPlayer.stop();
super.dispose();
}
@override
Widget build(BuildContext context) {
final itemsData = Provider.of<ItemsList>(context);
_nextCardHandler() async {
if (pageController.page.toInt() < itemsData.items.length - 1) {
pageController.animateToPage(pageController.page.toInt() 1,
duration: Duration(milliseconds: 400), curve: Curves.easeIn);
} else {
pageController.animateToPage(0,
duration: Duration(milliseconds: 400), curve: Curves.easeIn);
}
if (playing) {
var res = await audioPlayer.stop();
if (res == 1) {
setState(() {
playing = false;
});
}
}
}
_prevCardHandler() async {
if (pageController.page.toInt() == 0) {
pageController.animateToPage(itemsData.items.length - 1,
duration: Duration(milliseconds: 400), curve: Curves.easeIn);
} else {
pageController.animateToPage(pageController.page.toInt() - 1,
duration: Duration(milliseconds: 400), curve: Curves.easeIn);
}
if (playing) {
var res = await audioPlayer.stop();
if (res == 1) {
setState(() {
playing = false;
});
}
print('stop here');
}
}
void _getAudio(audio) async {
if (playing) {
var res = await audioPlayer.pause();
if (res == 1) {
setState(() {
playing = false;
});
}
print('pause uuuu');
} else {
var res = await audioPlayer.play(audio, isLocal: true);
await audioPlayer.setReleaseMode(ReleaseMode.LOOP);
if (res == 1) {
print('play 999');
setState(() {
playing = true;
});
}
}
}
return Scaffold(
appBar: AppBar(
backgroundColor: Theme.of(context).primaryColor,
title: Text(
itemsData.items[currentPage.round()].title,
),
iconTheme: IconThemeData(color: Theme.of(context).accentColor),
),
drawer: AppDrawer(),
body: PageView.builder(
controller: pageController,
itemCount: itemsData.items.length,
itemBuilder: (ctx, int itemIndex) {
return Container(
decoration: new BoxDecoration(
image: new DecorationImage(
image: NetworkImage(itemsData.items[itemIndex].image),
fit: BoxFit.cover,
),
),
child: Column(
mainAxisAlignment: MainAxisAlignment.end,
children: [
Container(
child: Row(
mainAxisAlignment: MainAxisAlignment.end,
children: [
SizedBox(
child: IconButton(
icon: Icon(Icons.favorite_border),
color: Theme.of(context).accentColor,
iconSize: 40,
onPressed: () {},
),
),
],
),
),
Expanded(
child: Padding(
padding: EdgeInsets.all(20),
),
),
Container(
color: Colors.black54,
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: <Widget>[
SizedBox(
child: IconButton(
icon: Icon(Icons.arrow_left_sharp),
color: Theme.of(context).accentColor,
iconSize: 80,
onPressed: _prevCardHandler,
),
),
SizedBox(
child: IconButton(
icon: Icon(playing == false
? Icons.play_circle_fill_outlined
: Icons.pause_circle_filled_outlined),
color: Theme.of(context).accentColor,
iconSize: 80,
onPressed: () =>
_getAudio(itemsData.items[itemIndex].audio),
),
),
SizedBox(
child: IconButton(
icon: Icon(Icons.arrow_right_sharp),
color: Theme.of(context).accentColor,
iconSize: 80,
onPressed: _nextCardHandler,
),
),
],
),
),
],
),
);
},
),
);
}
}
Комментарии:
1. Вы пробовали использовать
AppLifecycleState
viaWidgetsBindingObserver
? medium.com/pharos-production/flutter-app-lifecycle-4b0ab4a4211a2. Я еще не пробовал. Но я думаю, что попробую их обязательно. Спасибо.
Ответ №1:
По этой ссылке.
Вы можете запускать асинхронные события после super.dispose()
первого вызова. Итак, в вашем случае
@override
Future<void> dispose() async {
super.dispose(); //change here
await audioPlayer.stop();
}
Комментарии:
1. Спасибо @Mayb3Not, за ваш быстрый ответ. После того, как я переместил super.dispose(), ошибки нет.
2. рад помочь, пожалуйста, проголосуйте, если вы нашли это полезным 😉