Home > Blockchain >  Stop the timer if navigate to another screen on Flutter
Stop the timer if navigate to another screen on Flutter

Time:04-01

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();
  }
}

CodePudding user response:

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();

CodePudding user response:

The solution is to define a reference to the timer and cancel it on dispose.

enstade of this:

Timer(
            Duration(seconds: 38), //the wanted duration for the timer
            () => Navigator.pushReplacement(
                context,
                MaterialPageRoute(
                  builder: (context) => const HomeScreen(),
                )));

write this:

var timer = Timer(
                Duration(seconds: 38), //the wanted duration for the timer
                () => Navigator.pushReplacement(
                    context,
                    MaterialPageRoute(
                      builder: (context) => const HomeScreen(),
                    )));

and onDispose will be like this:

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

CodePudding user response:

to achive this you need to cancel timer when you click on skip button. so here i initialize timer in initstate method and when user click on skip button timer is cancelled and navigate to other page.

class _VideoAppState extends State<additionVideo> {
  late VideoPlayerController _controller; //the controller of the video player
  late Timer timer;
  @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 = 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) {
                  timer.cancel();
                  //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();
    timer.cancel();
  }
}

CodePudding user response:

Try it out:

onTap: (finish) {
              //Navigate to the questions page
              Navigator.push(
                context,
                MaterialPageRoute(builder: (context) => const HomeScreen()),
              );
             setState(() {
               _controller
                  .pause();
    });
               //stop the video when naviagte to the questions page
            },
  • Related