64

I have a home page which when clicked takes me to another page through navigates, do some operations in then press the back button which takes me back to the home page. but the problem is the home page doesn't get refreshed.

Is there a way to reload the page when i press the back button and refreshes the home page?

David
  • 1,071
  • 3
  • 11
  • 13

8 Answers8

84

You can trigger the API call when you navigate back to the first page like this pseudo-code

class PageOne extends StatefulWidget {
  @override
  _PageOneState createState() => new _PageOneState();
}

class _PageOneState extends State<PageOne> {
  _getRequests()async{

  }
  @override
  Widget build(BuildContext context) {
    return new Scaffold(
      body: new Center(
        child: new RaisedButton(onPressed: ()=>
        Navigator.of(context).push(new MaterialPageRoute(builder: (_)=>new PageTwo()),)
        .then((val)=>val?_getRequests():null),
      ),
    ));
  }
}

class PageTwo extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    //somewhere
    Navigator.pop(context,true);
  }
}

Or you can just use a stream if the API is frequently updated, the new data will be automatically updated inside your ListView

For example with firebase we can do this

stream: FirebaseDatabase.instance.reference().child(
      "profiles").onValue

And anytime you change something in the database (from edit profile page for example), it will reflect on your profile page. In this case, this is only possible because I am using onValue which will keep listening for any changes and do the update on your behalf.

Shady Aziza
  • 50,824
  • 20
  • 115
  • 113
  • 7
    Just replace ```.then((val)=>val?_getRequests():null)``` with ```.then((val)=>{_getRequests()})``` . Otherwise a ```bool != null exception``` will happen. – Luiz Vaz Jul 17 '19 at 00:39
29

(In your 1st page): Use this code to navigate to the 2nd page.

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.
  });
});

(In your 2nd page): Use this code to return back to the 1st page.

Navigator.pop(context);
CopsOnRoad
  • 237,138
  • 77
  • 654
  • 440
9

use result when you navigate back from nextScreen as follow :

Navigator.of(context).pop('result');

or if you are using Getx

Get.back(result: 'hello');

and to reload previous page use this function :

void _navigateAndRefresh(BuildContext context) async {
    final result = await Get.to(()=>NextScreen());//or use default navigation
    if(result != null){
      model.getEMR(''); // call your own function here to refresh screen
    }
  }

call this function instead of direct navigation to nextScreen

Mohamed Mansour
  • 197
  • 2
  • 4
3

The solution which I found is simply navigating to the previous page: In getx:

 return WillPopScope(
      onWillPop: () {
        Get.off(() => const PreviousPage());

        return Future.value(true);
      },
child: YourChildWidget(),

or if you want to use simple navigation then:

 Navigator.pushReplacement(context, MaterialPageRoute(builder: (context) =>PreviousPage() ,));
iDecode
  • 22,623
  • 19
  • 99
  • 186
Muhammad Umair Saqib
  • 1,287
  • 1
  • 9
  • 20
2

Simply i use this:

onPressed: () {
          Navigator.pop(context,
              MaterialPageRoute(builder: (context) => SecondPage()));
        },

this to close current page:

Navigator.pop

to navigate previous page:

MaterialPageRoute(builder: (context) => SecondPage())

In FirtsPage, me adding this for refresh on startUpPage:

 @override
  void initState() {
    //refresh the page here
    super.initState();
  }
mlatifr
  • 29
  • 4
0

For a more fine-grained, page-agnostic solution I came up with this Android Single LiveEvent mimicked behaviour.

I create such field inside Provider class, like:

SingleLiveEvent<int> currentYearConsumable = SingleLiveEvent<int>();

It has a public setter to set value. Public consume lets you read value only once if present (request UI refresh). Call consume where you need (like in build method).

You don't need Provider for it, you can use another solution to pass it.

Implementation:

/// Useful for page to page communication
/// Mimics Android SingleLiveEvent behaviour
/// https://stackoverflow.com/questions/51781176/is-singleliveevent-actually-part-of-the-android-architecture-components-library
class SingleLiveEvent<T> {
  late T _value;
  bool _consumed = true;

  set(T val) {
    _value = val;
    _consumed = false;
  }

  T? consume() {
    if (_consumed) {
      return null;
    } else {
      _consumed = true;
      return _value;
    }
  }
}

Michał Dobi Dobrzański
  • 1,449
  • 1
  • 20
  • 19
0

await the navigation and then call the api function.

await Navigator.of(context).pop(); await api call

Amit Jajoo
  • 220
  • 3
  • 7
0

You can do this with a simple callBack that is invoked when you pop the route. In the below code sample, it is called when you pop the route.

class HomePage extends StatefulWidget {
  @override
  _HomePageState createState() => new _HomePageState();
}

class _HomePageState extends State<HomePage> {
  _someFunction()async{
      Navigator.of(context).push(MaterialPageRoute(builder: (_)=> PageTwo(
         onClose():(){
            // Call setState here to rebuild this widget
            // or some function to refresh data on this page.
         }
     )));
   }

 @override
  Widget build(BuildContext context) {
     return SomeWidget();
 }
...
} // end of widget
class PageTwo extends StatelessWidget {
  final VoidCallback? onClose;
  PageTwo({Key? key, this.onClose}) : super(key: key);

  @override
  Widget build(BuildContext context) {
   
   return SomeWidget(
    onEvent():{ 
     Navigate.of(context).pop();
     onClose(); // call this wherever you are popping the route
   );
  }
}
Mahesh Jamdade
  • 17,235
  • 8
  • 110
  • 131