Home > database >  Flutter pause Timer when on screen. Stop when I jump to another screen. Resume when I get back on th
Flutter pause Timer when on screen. Stop when I jump to another screen. Resume when I get back on th

Time:11-08

I have two pages in flutter app. Even when i move to secondpage (using navigator.push), the timer still runs in background. ( I know it because i am printing it in terminal also). Also, I already tried canceling my Timer in dispose method. it does not work. Also, If I use navigator.pushReplacement, it solves the problem of Timer being run in background, but i wont be able to go back to this page.

here is my full code:

    import 'dart:async';
import 'package:flutter/material.dart';
import 'package:intl/intl.dart';
import 'package:provider/provider.dart';
import 'package:provider_2_practice/controller/controller_file.dart';
import 'new_screen.dart';

class MyHomePageUI extends StatefulWidget {
  @override
  State<MyHomePageUI> createState() => _MyHomePageUIState();
}

class _MyHomePageUIState extends State<MyHomePageUI> {

  Timer? timer ;
  String abc ='df-1'; //default value: 'df-1'

  @override
  void initState() {
    // TODO: implement initState
    super.initState();
    timer = Timer.periodic(Duration(seconds: 1), (Timer t) {
      if(mounted){
        setState( () {
          abc = DateFormat('hh:mm:ss a').format(DateTime.now());
        } );
      }
      print(abc);
    });
  }

@override
  void dispose() {
    // TODO: implement dispose
  print('test \n if you are seeing this, maybe you used Navigator.pushReplacement()');
  timer?.cancel();
    super.dispose();
  }


  @override
  Widget build(BuildContext context) {
    return Scaffold(
      backgroundColor: Colors.lightBlue[900],
      floatingActionButton: FloatingActionButton(
        onPressed: (){
          dispose();
          // Provider . of <MyController> (context, listen: false)  . addItemInList();
           Navigator.of(context).push(MaterialPageRoute(builder: (context) => NewScreen()));


          /*MyController con = MyController();
          con.addItemInList();*/
        },
        child: Icon(Icons.add,  color: Colors.white),
        backgroundColor: Colors.blue,
      ),


      body: Column(
        children: [
          SizedBox(height:100,),
          Text(abc, style: TextStyle(fontSize: 45, fontWeight: FontWeight.bold,color: Colors.white70),),
          Text('current time', style: TextStyle(  fontWeight: FontWeight.bold,color: Colors.white),),

        ],
      ),
    );
  }
}

CodePudding user response:

dispose method is only called once the page is finished and ready to be removed from the WidgetTree, In the first case when you use Navigator.push to navigate to another page, It won't remove the previous page and Navigator.pushReplacement replaces the first page and removes it from widget tree thus calls the dispose method.

So, to pause and resume after coming back to the first page, then you need to cancel timer before the navigator.push and await till it completes and resume after async is done

        void goToSecondpage () async {
              timer?.cancel();
              await Navigator.of(context).push(
                  MaterialPageRoute(builder: (context) => SecondWidget()));
              initTimer();
            }

Full code here

  • Related