35

I have a "list page". and an add page. User clicks "add page", goes to a new page where they add some entity. Then I pop the Navigator, and user goes back to "list page".

At this point, I want to get notified somehow - callback maybe? override a method, I am not really sure - and re-read the information from database.

Is there a hook like this in Flutter? Or is there another pattern that I should use?

Boken
  • 4,825
  • 10
  • 32
  • 42
Arash
  • 11,697
  • 14
  • 54
  • 81
  • See this: https://medium.com/@najeira/how-to-handle-screen-transitions-in-flutter-b39dcb2675f You can use NavigatorObserver and RouteObserver to receive events related to screen transitions. – najeira Apr 20 '18 at 03:16
  • Possible duplicate of [Flutter - Always execute a function when the page appears](https://stackoverflow.com/questions/47027124/flutter-always-execute-a-function-when-the-page-appears) – Shady Aziza Apr 20 '18 at 09:02
  • Possible duplicate of [Force Flutter navigator to reload state when popping](https://stackoverflow.com/questions/49804891/force-flutter-navigator-to-reload-state-when-popping) – Jannie Theunissen Oct 10 '19 at 07:39

7 Answers7

36

The Navigator.push method returns a future of the generic type of the Route:

Navigator.of(context)
  .push(new MaterialPageRoute<String>(...))
  .then((String value) {
    print(value);
  });

And inside the new route, when you have the value you need:

Navigator.of(context).pop('String');
Ian
  • 2,944
  • 1
  • 19
  • 19
23

If at your list page, you create function let say retrieveData() to read list of the data then call it inside initState, if you're using pushNamed route, the simple solution would be

Navigator.pushNamed(context, '/adddatapage').whenComplete(retrieveData());

If you're using push route,

Navigator.of(context).push(new MaterialPageRoute(builder: (context) => AddPage())).whenComplete(retrieveData);

That should be enough. No need to additional code on the add page. This will be works if user press back button also, again, without additional code in the add page.

adadion
  • 746
  • 1
  • 10
  • 24
  • 2
    I'm using Get, so I'm not dealing directly with Navigator.of(context), but simpler `Get.to()`. `.whenComplete()` helped nevertheless – Csaba Toth Jan 16 '21 at 07:28
  • 1
    @CsabaToth Yep, the magic tool here is whenComplete() method itself. – adadion Jan 18 '21 at 09:30
9

Adding an option to @ian 's answer

Navigator.of(context)
  .push(new MaterialPageRoute<String>(...))
  .then((value) => setState(() => {}));

This worked for me. This will rebuild whenever the page is loaded.

Lee Taylor
  • 7,761
  • 16
  • 33
  • 49
Aravin
  • 6,605
  • 5
  • 42
  • 58
  • 1
    What did you add, a `setState` call? You could have edited his answer instead of writing your own. – iDecode Jan 25 '21 at 14:06
2

Write below code when redirect to screen 2,

Navigator.pushNamed(context, '/screen2').then((_) {
  // This block runs when you have returned back from screen 2.
  setState(() {
    // code here to refresh data
  });
});

Use

Navigator.pop(context);

in screen 2 to back to screen 1

Hardik Hirpara
  • 2,594
  • 20
  • 34
1

i use Navigator.pushAndRemoveUntil, it will refresh the page and load the data again, this is example :

Navigator.pushAndRemoveUntil(
        context,
        MaterialPageRoute(
            builder: (context) =>
                CustomerMainPage()),
            (Route<dynamic> route) =>
        false);

Update 2023, if you use GetX you can do with this sample :

Get.toNamed(
  routeName,
  arguments: params,
)?.whenComplete(() => doTheProcess());
Cevin Ways
  • 984
  • 11
  • 13
1

I passed a callback method into the "add" page as a Navigator route argument. The callback is a method in my list page. The "add" page executes the callback when exiting. The callback method then simply refreshes the data and calls setState to refresh the screen.

My architecture is using Provider and viewmodels, but it should be straight-forward in a standard app as well.

Nick Wright
  • 1,403
  • 13
  • 19
1

For named route:

Navigator.pushNamed(context, '/page2').then((_) {
  // This block runs when you have returned back to the 1st Page from 2nd.
  setState(() {
    // Call setState to refresh the page.
  });
});

For unnamed route:

Navigator.push(context, MaterialPageRoute(builder: (_) => Page2())).then((_) {
  // This block runs when you have come back to the 1st Page from 2nd.
  setState(() {
    // Call setState to refresh the page.
  });
});
CopsOnRoad
  • 237,138
  • 77
  • 654
  • 440