Force Flutter navigator to reload state when popping

前端 未结 14 2071
情书的邮戳
情书的邮戳 2020-11-28 22:54

I have one StatefulWidget in Flutter with button, which navigates me to another StatefulWidget using Navigator.push(). On second widge

相关标签:
14条回答
  • 2020-11-28 23:13

    For me worked:

    ...
    onPressed: (){pushUpdate('/somePageName');}
    ...
    
    pushUpdate (string pageName) async {      //in the same class
      await pushPage(context, pageName);
      setState(() {});
    }
    
    
    //---------------------------------------------
    //general sub
    pushPage (context, namePage) async {
      await Navigator.pushNamed(context, namePage);
    }
    

    In this case doesn't matter how you pop (with button in UI or "back" in android) the update will be done.

    0 讨论(0)
  • 2020-11-28 23:15

    If you are using an alert dialog then you can use a Future that completes when the dialog is dismissed. After the completion of the future you can force widget to reload the state.

    First page

    onPressed: () async {
        await showDialog(
           context: context,
           builder: (BuildContext context) {
                return AlertDialog(
                     ....
                );
           }
        );
        setState(() {});
    }
    

    In Alert dialog

    Navigator.of(context).pop();
    
    0 讨论(0)
  • 2020-11-28 23:17

    Today I faced the same situation but I managed to solve it in much easier way, I just defined a global variable which was used in the first stateful class , and when I navigate to a second stateful widget I let it update the value of the global variable which automatically forces the first widget to update. Here is an example (I wrote it in hurry so I didn't put a scaffold or a material app, I just wanted to Illustrate my point):

    import 'package:flutter/material.dart';
    int count = 0 ;
    
    class FirstPage extends StatefulWidget {
    FirstPage({Key key}) : super(key: key);
    
    @override
    _FirstPageState createState() => _FirstPageState();
    }
    
    class _FirstPageState extends State<FirstPage> {
    @override
    Widget build(BuildContext context) {
    return InkWell(
    onTap(){
    Navigator.of(context).push(MaterialPageRoute(builder: (context) =>
                      new SecondPage());
    },
    child: Text('First', style : TextStyle(fontSize: count == 0 ? 20.0 : 12.0)),
    ),
    
    }
    
    
    class SecondPage extends StatefulWidget {
    SecondPage({Key key}) : super(key: key);
    
    @override
    _SecondPageState createState() => _SecondPageState();
    }
    
    class _SecondPageState extends State<SecondPage> {
    @override
    Widget build(BuildContext context) {
    return IconButton(
             icon: new Icon(Icons.add),
             color: Colors.amber,
             iconSize: 15.0,
             onPressed: (){
             count++ ;
             },
           ),
         }
    
    0 讨论(0)
  • 2020-11-28 23:20

    You can pass back a dynamic result when you are popping the context and then call the setState((){}) when the value is true otherwise just leave the state as it is.

    I have pasted some code snippets for your reference.

    handleClear() async {
        try {
          var delete = await deleteLoanWarning(
            context,
            'Clear Notifications?',
            'Are you sure you want to clear notifications. This action cannot be undone',
          );
          if (delete.toString() == 'true') {
            //call setState here to rebuild your state.
    
          }
        } catch (error) {
          print('error clearing notifications' + error.toString());
                 }
      }
    
    
    
    Future<bool> deleteLoanWarning(BuildContext context, String title, String msg) async {
    
      return await showDialog<bool>(
            context: context,
            child: new AlertDialog(
              title: new Text(
                title,
                style: new TextStyle(fontWeight: fontWeight, color: CustomColors.continueButton),
                textAlign: TextAlign.center,
              ),
              content: new Text(
                msg,
                textAlign: TextAlign.justify,
              ),
              actions: <Widget>[
                new Container(
                  decoration: boxDecoration(),
                  child: new MaterialButton(
                    child: new Text('NO',),
                    onPressed: () {
                      Navigator.of(context).pop(false);
                    },
                  ),
                ),
                new Container(
                  decoration: boxDecoration(),
                  child: new MaterialButton(
                    child: new Text('YES', ),
                    onPressed: () {
                      Navigator.of(context).pop(true);
                    },
                  ),
                ),
              ],
            ),
          ) ??
          false;
    }
    

    Regards, Mahi

    0 讨论(0)
  • 2020-11-28 23:20

    Needed to force rebuild of one of my stateless widgets. Did't want to use stateful. Came up with this solution:

    await Navigator.of(context).pushNamed(...);
    ModalRoute.of(enclosingWidgetContext);
    

    Note that context and enclosingWidgetContext could be the same or different contexts. If, for example, you push from inside StreamBuilder, they would be different.

    We don't do anything here with ModalRoute. The act of subscribing alone is enough to force rebuild.

    0 讨论(0)
  • 2020-11-28 23:24

    my solution went by adding a function parameter on SecondPage, then received the reloading function which is being done from FirstPage, then executed the function before the Navigator.pop(context) line.

    FirstPage

    refresh() {
    setState(() {
    //all the reload processes
    });
    }
    

    then on pushing to the next page...

    Navigator.push(context, new MaterialPageRoute(builder: (context) => new SecondPage(refresh)),);
    

    SecondPage

    final Function refresh;
    SecondPage(this.refresh); //constructor
    

    then on before the navigator pop line,

    widget.refresh(); // just refresh() if its statelesswidget
    Navigator.pop(context);
    

    Everything that needs to be reloaded from the previous page should be updated after the pop.

    0 讨论(0)
提交回复
热议问题