27

I have a page that is called from bottom tab nav which executes a initState function, I then navigate to a page via button click that has details and actions to take, however when I click the back button to goto originating page, the initState does not run again, I have found out that because Flutter does not destroy the page when you put one on top, since the NAV is not on new page as its not in the menu, how do I make initState run again on clicking back button or is there another way to listen for that navigate from back button and run the code that needs to update data?

Any help would be great.

Robert
  • 5,347
  • 13
  • 40
  • 57
  • You do not want to call initState again, it is easier to just change the state depending on Navigator.pop – Shady Aziza Feb 03 '18 at 01:56
  • How do I do that, this is the back button in the appBar, is there a way to affect that with a pop? – Robert Feb 03 '18 at 12:36
  • Check my answer down below – Shady Aziza Feb 03 '18 at 13:21
  • @Robert see this link, i have answered this question on how to call initState or update data when back button on navigation bar was pressed https://stackoverflow.com/questions/51927885/flutter-back-button-with-return-data – ArgaPK Nov 08 '18 at 10:25

4 Answers4

42

You can listen to the pop with WillPopScope (Creates a widget that registers a callback to veto attempts by the user to dismiss the enclosing [ModalRoute]. -> from documentation):

@override
Widget build(BuildContext context) {
 return WillPopScope(
  onWillPop: () {
    print('Backbutton pressed (device or appbar button), do whatever you want.');

    //trigger leaving and use own data
    Navigator.pop(context, false);

    //we need to return a future
    return Future.value(false);
  },
  child: Scaffold(
  ...
  ),
 );
}

Hopefully I got your question right and that helps :)!

novas1r1
  • 1,803
  • 21
  • 28
  • 1
    Thanks! This is usually the way to go, since you would usually want to intercept the "popping", not just the back button of the AppBar. By the way, I just discovered a strange behaviour of WillPopScope in iOS, since it disables swipe back. See: https://github.com/flutter/flutter/issues/14203. – Ferran Maylinch Dec 21 '19 at 22:43
30

You can override the default back arrow on the AppBarand then specify the value you would like to return to trigger the change of the state when Navigator.pop is called:

Pseudo-Code

so you need to have something like this in your onPressed callback of your navigation button

onPressed: ()async{
            var nav = await Navigator.of(context).push(newRoute);
            if(nav==true||nav==null){
              //change the state
            }
          },

and in your newRoute you should have something like this

new AppBar(
        leading: new IconButton(
          icon: new Icon(Icons.arrow_back),
          onPressed: (){Navigator.pop(context,true)}
        ),

I am checking for both values null or true because the null value is returned when the user hits the BackButton on android screen (the one in the bottom of the screen). I also believe the null will also be returned with the default BackButton in Flutter so you do not actually need to override the leading property, but I have not checked that myself, so it may be worth checking.

Shady Aziza
  • 50,824
  • 20
  • 115
  • 113
2
//if you want to perform  any operation on back button so you can use WillPopScope Widget and managed your code inside onWillpop method 

   
 @override
 Widget build(BuildContext context) {
        return WillPopScope( 

        child:Column()),

        onWillPop: onBackPress);
   }
        
   
// this is onBackPress method
 Future<bool> onBackPress() {
        // your code 
   return Future.value(false);
 }
adarsh
  • 403
  • 3
  • 8
0

In my case, just invoking whenComplete() is enough. Take a look of the example :

Navigator.push(context,
        MaterialPageRoute(builder: (context) => const YourRoute()))
    .whenComplete(() {
  // Do something when back to previous state
});
Johan
  • 207
  • 4
  • 14