Search code examples
flutterdartvideotimernavigation

Stop the timer if navigate to another screen on Flutter


I have a video playing till the wanted duration (Timer). When the timer is done, it will navigate to another screen. Also, I have a skip button if the user wanted to skip the video to go to the next screen. Here is the problem, if the user clicks the skip button, the timer is still running and the screen will be updated even the user skipped the video. I want the timer to stop when the user chooses to skip.

The code:

//imports

class _VideoAppState extends State<additionVideo> {
  late VideoPlayerController _controller; //the controller of the video player

  @override
  void initState() {
    super.initState();
    _controller = VideoPlayerController.asset('assets.mp4')
      ..initialize().then((_) {
        _controller.setVolume(1.0); //video sound (volume)
        _controller.setLooping(false); //do not repeat the video when finish
        _controller.play(); //play the video

        //navigate to the question page when the video is finished
        Timer(
            Duration(seconds: 38), //the wanted duration for the timer
            () => Navigator.pushReplacement(
                context,
                MaterialPageRoute(
                  builder: (context) => const HomeScreen(),
                )));

        setState(() {});
      });
  }

  @override
  Widget build(BuildContext context) {
    //fit to the screen
    double width = MediaQuery.of(context).size.width;
    double height = MediaQuery.of(context).size.height;
    return MaterialApp(
      home: Stack(
        children: <Widget>[
          SizedBox.expand(
            child: FittedBox(
              fit: BoxFit.cover,
              child: SizedBox(
                width: width,
                height: height,
                child: VideoPlayer(_controller),
              ),
            ),
          ),
          Container(
            alignment: Alignment.topRight,
            padding: EdgeInsets.all(30.0),
            child: NiceButtons(
                //A skip button to go to the questions page
                stretch: false,
                startColor: Colors.lightBlueAccent,
                endColor: Colors.lightBlueAccent,
                borderColor: Color(0xFF3489e9),
                width: 100.0,
                height: 60,
                borderRadius: 60,
                gradientOrientation: GradientOrientation.Horizontal,
                onTap: (finish) {
                  //Navigate to the questions page
                  Navigator.push(
                    context,
                    MaterialPageRoute(builder: (context) => const HomeScreen()),
                  );
                  _controller
                      .pause(); //stop the video when naviagte to the questions page
                },
                child: Text('skip',
                    textAlign: TextAlign.center,
                    style: TextStyle(
                        decoration: TextDecoration.none,
                        fontSize: 20.0,
                        color: Colors.white,
                        fontFamily: 'ReadexPro-Regular',
                        fontWeight: FontWeight.bold))),
          ),
        ],
      ),
      debugShowCheckedModeBanner: false,
    );
  }

  @override
  void dispose() {
    super.dispose();
    _controller.dispose();
  }
}

Solution

  • declare timer

    late Timer timer;
    

    initialize timer

    @override
      void initState() {
        super.initState();
        timer = Timer(
                Duration(seconds: 38),
                    () => Navigator.pushReplacement(
                    context,
                    MaterialPageRoute(
                      builder: (context) => const HomeScreen(),
                    )));
    
            setState(() {});
      }
    
    @override
      void dispose() {
        super.dispose();
        timer.cancel();
      }
    

    cancel timer on onTap or onPressed function or dispose the timer

    timer.cancel();