Flutter - Always execute a function when the page appears

后端 未结 5 1114
暗喜
暗喜 2021-01-20 03:56

How could I make the name() function run whenever the Page1 page appeared?

In the code below before going to Page2 I execute t

相关标签:
5条回答
  • 2021-01-20 04:32

    You can use RouteObserves if you want to execute some function whenever your page appears, you will have to implement RouteAware on the page where you want to run execute the function whenever the screens appears, you're gonna have to do something like this on ur Page1

    final RouteObserver<PageRoute> routeObserver = RouteObserver<PageRoute>(); // add this on your main class
    void main() {
      runApp(MaterialApp(
        home: Container(),
        navigatorObservers: [routeObserver], // add observer here;
      ));
    } 
    
    
    
    
    
    // your page where func should run whenever this page appears
    class MyHomePage extends StatefulWidget with RouteAware {
      @override
      _MyHomePageState createState() => _MyHomePageState();
    }
    
    class _MyHomePageState extends State<MyHomePage> {
      String nameScreen = "";
    
      String name() {
        return 'foo1';
      }
    
      @override
      void initState() {
        super.initState();
        this.nameScreen = "From initState";
    
      }
    
     @override
      void didChangeDependencies() {
        super.didChangeDependencies();
        routeObserver.subscribe(this, ModalRoute.of(context));
      }
    
      @override
      void dispose() {
        routeObserver.unsubscribe(this);
        super.dispose();
      }
    
    // implementing RouteAware method
    void didPush() {
    // Route was pushed onto navigator and is now topmost route.
        name(); // your func goes here
      }
    
    
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          appBar: AppBar(
            title: const Text('Page 1'),
            backgroundColor: Color(0xFF26C6DA),
          ),
          body: Center(
            child: Column(
              mainAxisAlignment: MainAxisAlignment.center,
              children: <Widget>[
                RaisedButton(
                  child: const Text('go to Page2'),
                  onPressed: () async {
                    //dispose(); ///No need for dispose
                    String result = await Navigator.of(context).pushNamed('/page2');
    
                      setState((){
                        this.nameScreen = result;
                      });
    
                  },
                ),
                Text(
                  '$nameScreen',
                ),
              ],
            ),
          ),
        );
      }
    }
    

    you can head over to this link for more explanation https://api.flutter.dev/flutter/widgets/RouteObserver-class.html

    0 讨论(0)
  • 2021-01-20 04:38

    Say you want to navigate from page 1 to page 2 and immediately after page 2 loads execute a function in page 2 (useful for showing a dialog immediately when page 2 loads) :

    You can do this by adding in initState or didChangeDependencies of page 2 :

     WidgetsBinding.instance.addPostFrameCallback((timeStamp) {
        // Function to execute
      });
    

    If you want to add some logic to put a condition before executing the function, simply push an argument in your page 1 :

    Navigator.of(context).pushNamed("/page-2", arguments : true)
    

    Finnaly the code in page 2 becomes:

     _functionToExecute(){
      print("done");
      }
     @override
     void didChangeDependencies() {
     
      WidgetsBinding.instance.addPostFrameCallback((timeStamp) {
        if(ModalRoute.of(context).settings.arguments)
        _functionToExecute()
      });
     }
    
    0 讨论(0)
  • 2021-01-20 04:55

    There is no need to call dispose at all when you are willing to pop and change State later, since dispose will remove the current object from the tree, which does not translate to the logic you are trying to develop.

    You can indeed override the BackButton and pass the same call of Navigator.pop(context, result) to it. Check the following example I have tweaked your code a little bit to show you the difference between each State of your nameScreen field. I hope this helps you.

    class MyHomePage extends StatefulWidget {
      @override
      _MyHomePageState createState() => _MyHomePageState();
    }
    
    class _MyHomePageState extends State<MyHomePage> {
      String nameScreen = "";
    
      String name() {
        return 'foo1';
      }
    
      @override
      void initState() {
        super.initState();
        this.nameScreen = "From initState";
    
      }
    
    @override
    void dipose(){
        super.dispose();
    }
    
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          appBar: AppBar(
            title: const Text('Page 1'),
            backgroundColor: Color(0xFF26C6DA),
          ),
          body: Center(
            child: Column(
              mainAxisAlignment: MainAxisAlignment.center,
              children: <Widget>[
                RaisedButton(
                  child: const Text('go to Page2'),
                  onPressed: () async {
                    //dispose(); ///No need for dispose
                    String result = await Navigator.of(context).pushNamed('/page2');
    
                      setState((){
                        this.nameScreen = result;
                      });
    
                  },
                ),
                Text(
                  '$nameScreen',
                ),
              ],
            ),
          ),
        );
      }
    }
    
    class Page2 extends StatelessWidget{
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          appBar: AppBar(
              leading: IconButton(icon: Icon(Icons.arrow_back), onPressed: ()async{
                Navigator.pop(context,"From BackButton");
              }),
              title: const Text('Page 2'),
              backgroundColor: Color(0xFFE57373)
          ),
          body: Center(
            child: Column(
              mainAxisAlignment: MainAxisAlignment.center,
              children: <Widget>[
                RaisedButton(
                    child: const Text('go back to Page1'),
                    onPressed: () {
                      Navigator.pop(context, "From RaisedButton");
                    }
                ),
              ],
            ),
          ),
        );
      }
    
    0 讨论(0)
  • 2021-01-20 04:56

    One way of doing this is to use the .whenComplete() method on the Navigator widget.

    Suppose you are going to the second page from the first page. Here you have to pass the functionThatSetsTheState as a pointer to the navigation part of your code.

    The function looks like this and should be in a Stateful Widget.

    void functionThatSetsTheState(){
     setState(() {});
    }
    

    Your navigation code for OnPressed, OnTap, OnLongPress, etc.

    Navigator.of(context).push(MaterialPageRoute(builder: (BuildContext context) => SecondPage())).whenComplete(() => {functionThatSetsTheState()});
    
    0 讨论(0)
  • 2021-01-20 04:57

    You can override the back button on the second screen. And instead of system closing, do

    `WillPopScope(
        onWillPop: () {
           print('back pressed');
           Navigator.pop(context, "From BackButton");
           return true;
          },
        child: Scaffold(...)`
    
    0 讨论(0)
提交回复
热议问题