Home > OS >  to stop periodic function calling when navigate to another screen in flutter
to stop periodic function calling when navigate to another screen in flutter

Time:06-08

i have two screens A and B.In screen A iam calling a function periodically(i.e every 5 seconds).At the time of navigating to screen B i need to stop the function calling and when its back to screen A, the function call should be resumed.

Is there any way to do it?

CodePudding user response:

Navigator doesn't expose the current route.

What you can do instead is use Navigator.popUntil(callback) as popUtil pass to the callback the current Route, which includes it's name and stuff.

final newRouteName = "/NewRoute";
bool isNewRouteSameAsCurrent = false;

Navigator.popUntil(context, (route) {
if (route.settings.name == newRouteName) {
isNewRouteSameAsCurrent = true;
}
return true;
});

if (!isNewRouteSameAsCurrent) {
Navigator.pushNamed(context, newRouteName);
}

  

Use This bool to check current screen and toggle your function .

CodePudding user response:

From what i see is you can use the Timer class in the widget and manupulate based on your needs, I have created a sample example for you.


import 'package:flutter/material.dart';

void main() {
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return const MaterialApp(
      home: PageOne()

    );
  }
}


class PageOne extends StatefulWidget {
  const PageOne({Key? key}) : super(key: key);

  @override
  _PageOneState createState() => _PageOneState();
}

class _PageOneState extends State<PageOne> {

  Timer? timer;

  @override
  void initState() {
    // TODO: implement initState
    super.initState();

    timer = Timer.periodic(const Duration(seconds: 2), (timer) {

     printMethod("init");

    });


  }


  printMethod(String type){
    print("This is the $type print statement ");
  }


  @override
  void dispose() {
    super.dispose();
    timer?.cancel();
    print("First Page timer cancelled");
  }



  @override
  Widget build(BuildContext context) {
    return  Scaffold(
      body: Center(
        child: TextButton(onPressed: () async {
          timer?.cancel();
         var result =  await Navigator.push(context, MaterialPageRoute(builder: (context)=> const PageTwo() ));
         if(result)
           {

             timer = Timer.periodic(const Duration(seconds: 2), (timer) {

               printMethod("init");

             });

           }
        }, child: const Text("go to next page"),),
      ),
    );
  }
}



class PageTwo extends StatefulWidget {
  const PageTwo({Key? key}) : super(key: key);

  @override
  _PageTwoState createState() => _PageTwoState();
}

class _PageTwoState extends State<PageTwo> {
  @override
  Widget build(BuildContext context) {
    return  Scaffold(
      appBar: AppBar(title: Text("Page two"),),
      body: Center(
        child: TextButton(onPressed: () async {
          Navigator.of(context).pop(true);

        }, child: const Text("go to prev page"),),
      ),
    );
  }
}

Let me know if it works

CodePudding user response:

You can simply use bool to handle this case as follows :

 class _ScreenAState extends State<ScreenA> {
  bool runPeriodicFun = true;

  void periodicFun() {
    if (runPeriodicFun) {
      //write your periodic logic
    }
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: InkWell(
          onTap: () {
            setState(() {
              runPeriodicFun = false;
            });
            Navigator.push(
                    context,
                    MaterialPageRoute(
                        builder: (BuildContext context) => ScreenB()))
                .then((value) {
              setState(() {
                runPeriodicFun = true;
              });
              periodicFun();
            });
          },
          child: Container()),
    );
  }
}

when you go to Screen B then runPeriodicFun set to false and coming back to Screen A runPeriodicFun set to true. So it will use periodicFun block only when runPeriodicFun is true.

You will receive callback in then block in the Navigator.push method.

CodePudding user response:

what i did is that, in timer function i checked the current page is at top of stack by

ModalRoute.of(context)!.isCurrent

what it did is that it will check the page by context which we pass if the page is at top it will continue the timer, if it navigates to another page then the above code will return false. In false, i just stop the timer.

 if(ModalRoute.of(context)!.isCurrent){
    //timer running
  }else{
    _timer?.cancel();
  }

so if the page is same timer will perform otherwise it will stop the timer.

Now for resuming the timer, under the build in screen where you called i just called the function from where timer get activated.

Widget build(BuildContext context) {
 //call timer function
return SafeArea()}

i think this might solve the problem. if anyone identify any problem please comment it.

  • Related