flutterdart

Stop Play Music after leaving the page in Flutter


In my Flutter app I'm using audioplayers: ^0.17.0 to play music. When I play music and want to leave the page I want to stop playing music. For that purpose I'm using dispose(). And it looks like it is working. The problem that I'm getting is that I've got an error in the console. I think it is because I'm using async, but I'm not sure how to fix it. Or maybe there is a different solution that I can use for this purpose. Any suggestions?

Here are my code and error:

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,
                        ),
                      ),
                    ],
                  ),
                ),
              ],
            ),
          );
        },
      ),
    );
  }
}

enter image description here


Solution

  • According to this link.

    You can run asynchronous events after calling super.dispose() first. So in your case

      @override
      Future<void> dispose() async {
        super.dispose(); //change here
        await audioPlayer.stop();
        
      }