Home > Enterprise >  How to Refresh State from Navigator Pop in Flutter
How to Refresh State from Navigator Pop in Flutter

Time:03-11

I want to refresh the state when calling Navigator Pop / Navigator Pop Until. While I was doing some research, I finally found this article Flutter: Refresh on Navigator pop or go back. From the code in the article, it can work fine.

But there is a problem when I use the widget tree, for example like the code below:

import 'package:flutter/material.dart';

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Refresh on Go Back',
      home: HomePage(),
    );
  }
}

Home Page - Parent Class

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

class _HomePageState extends State<HomePage> {
  int id = 0;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Home'),
      ),
      body: Center(
        child: Column(
          mainAxisSize: MainAxisSize.min,
          children: <Widget>[
            Text(
              'Data: $id',
              style: Theme.of(context).textTheme.headline5,
            ),
            ButtonWidget(),
          ],
        ),
      ),
    );
  }
  
  void refreshData() {
    id  ;
  }

  onGoBack(dynamic value) {
    refreshData();
    setState(() {});
  }
}

Button Widget - Widget Class

class ButtonWidget extends StatelessWidget{
  @override
  Widget build(BuildContext context) {
    return RaisedButton(
      onPressed: (){
        Navigator.push(context, MaterialPageRoute(builder: (context) => 
         SecondPage())).then(onGoBack);

        // The Problem is Here
        // How to call a Method onGoBack from HomePage Class
      }
    );
  }
}

SecondPage

class SecondPage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Second Page'),
      ),
      body: Center(
        child: RaisedButton(
          onPressed: () {
            Navigator.pop(context);
          },
          child: Text('Go Back'),
        ),
      ),
    );
  }
}

Or is there another solution to refresh the state class when calling Navigator Pop / Navigator Pop Until?

CodePudding user response:

re-write your Button's class like this:

class ButtonWidget extends StatelessWidget{

  final Function onGoBack;

  ButtonWidget({this.onGoBack})

  @override
  Widget build(BuildContext context) {
    return RaisedButton(
        onPressed: (){
          Navigator.push(context, MaterialPageRoute(builder: (context) =>
              SecondPage())).then(onGoBack);
//to avoid any np exception you can do this: .then(onGoBack ?? () => {})

          // The Problem is Here
          // How to call a Method onGoBack from HomePage Class
        }
    );
  }
}

And add the onGoBack function as a parameter from the home page like this:

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

class _HomePageState extends State<HomePage> {
  int id = 0;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Home'),
      ),
      body: Center(
        child: Column(
          mainAxisSize: MainAxisSize.min,
          children: <Widget>[
            Text(
              'Data: $id',
              style: Theme.of(context).textTheme.headline5,
            ),
            ButtonWidget(onGoBack: onGoBack),
          ],
        ),
      ),
    );
  }
  
  void refreshData() {
    id  ;
  }

  onGoBack(dynamic value) {
    refreshData();
    setState(() {});
  }
}

CodePudding user response:

you must sent function on widget

     class ButtonWidget extends StatelessWidget{
        final Function(dynamic)? refresh;
        const ButtonWidget({this.refresh})
          @override
          Widget build(BuildContext context) {
            return RaisedButton(
              onPressed: ()async {
                await Navigator.push(context, MaterialPageRoute(builder: (context) => 
                 SecondPage()));
if(refresh!=null){
refresh!("your params");
}
        
        
                // The Problem is Here
                // How to call a Method onGoBack from HomePage Class
              }
            );
          }
        }

and you can use widget

ButtonWidget(
refresh:onGoBack
)

CodePudding user response:

Try this, it just you are calling method out of scope

import 'package:flutter/material.dart';

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Refresh on Go Back',
      home: HomePage(),
    );
  }
}

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

class _HomePageState extends State<HomePage> {
  int id = 0;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Home'),
      ),
      body: Center(
        child: Column(
          mainAxisSize: MainAxisSize.min,
          children: <Widget>[
            Text(
              'Data: $id',
              style: Theme.of(context).textTheme.headline5,
            ),
            ButtonWidget(
              refresh: onGoBack,
            )
          ],
        ),
      ),
    );
  }

  void refreshData() {
    id  ;
  }

  onGoBack(dynamic value) {
    refreshData();
    setState(() {});
  }
}

class ButtonWidget extends StatelessWidget {
  final Function(dynamic)? refresh;

  ButtonWidget({Key? key, this.refresh}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    print(refresh);
    return RaisedButton(onPressed: () async {
      await Navigator.push(
              context, MaterialPageRoute(builder: (context) => SecondPage()))
          .then((value) => refresh!("okay"));
    });
  }
}

class SecondPage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Second Page'),
      ),
      body: Center(
        child: RaisedButton(
          onPressed: () {
            Navigator.pop(context);
          },
          child: Text('Go Back'),
        ),
      ),
    );
  }
}

  • Related