弹出时强制颤动导航器重新加载状态

问题描述 投票:12回答:4

我在Flutter有一个StatefulWidget按钮,使用StatefulWidget导航我到另一个Navigator.push()。在第二个小部件上,我正在改变全局状态(一些用户首选项)。当我从第二个小部件返回到第一个小部件时,使用Navigator.pop()第一个小部件处于旧状态,但我想强制它重新加载。知道怎么做吗?我有一个想法,但它看起来很难看:

  1. 弹出以删除第二个小部件(当前一个)
  2. 再次弹出以删除第一个小部件(上一个)
  3. 推送第一个小部件(它应该强制重绘)
dart flutter
4个回答
13
投票

你可以在这里做几件事。 @ Mahi的回答虽然正确可能会更简洁一些,但实际上使用push而不是showDialog,因为OP正在询问。这是一个使用Navigator.push的示例:

import 'package:flutter/material.dart';

class SecondPage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return new Container(
      color: Colors.green,
      child: new Column(
        children: <Widget>[
          new RaisedButton(
            onPressed: () => Navigator.pop(context),
            child: new Text("back"),
          ),
        ],
      ),
    );
  }
}

class FirstPage extends StatefulWidget {
  @override
  State<StatefulWidget> createState() => new FirstPageState();
}

class FirstPageState extends State<FirstPage> {

  Color color = Colors.white;

  @override
  Widget build(BuildContext context) {
    return new Container(
      color: color,
      child: new Column(
        children: <Widget>[
          new RaisedButton(
              child: new Text("next"),
              onPressed: () {
                Navigator
                    .push(
                  context,
                  new MaterialPageRoute(builder: (context) => new SecondPage()),
                )
                    .then((value) {
                  setState(() {
                    color = color == Colors.white ? Colors.grey : Colors.white;
                  });
                });
              }),
        ],
      ),
    );
  }
}

void main() => runApp(
      new MaterialApp(
        builder: (context, child) => new SafeArea(child: child),
        home: new FirstPage(),
      ),
    );

但是,还有另一种方法可以很好地适应您的用例。如果你使用global作为影响第一页构建的东西,你可以使用InheritedWidget来定义你的全局用户首选项,每次更改它们时你的FirstPage都会重建。这甚至可以在无状态小部件中工作,如下所示(但也应该在有状态小部件中工作)。

flutter中的inheritedWidget的一个例子是应用程序的主题,虽然它们在一个小部件中定义它,而不是像我在这里那样直接构建它。

import 'package:flutter/material.dart';
import 'package:meta/meta.dart';

class SecondPage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return new Container(
      color: Colors.green,
      child: new Column(
        children: <Widget>[
          new RaisedButton(
            onPressed: () {
              ColorDefinition.of(context).toggleColor();
              Navigator.pop(context);
            },
            child: new Text("back"),
          ),
        ],
      ),
    );
  }
}

class ColorDefinition extends InheritedWidget {
  ColorDefinition({
    Key key,
    @required Widget child,
  }): super(key: key, child: child);

  Color color = Colors.white;

  static ColorDefinition of(BuildContext context) {
    return context.inheritFromWidgetOfExactType(ColorDefinition);
  }

  void toggleColor() {
    color = color == Colors.white ? Colors.grey : Colors.white;
    print("color set to $color");
  }

  @override
  bool updateShouldNotify(ColorDefinition oldWidget) =>
      color != oldWidget.color;
}

class FirstPage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    var color = ColorDefinition.of(context).color;

    return new Container(
      color: color,
      child: new Column(
        children: <Widget>[
          new RaisedButton(
              child: new Text("next"),
              onPressed: () {
                Navigator.push(
                  context,
                  new MaterialPageRoute(builder: (context) => new SecondPage()),
                );
              }),
        ],
      ),
    );
  }
}

void main() => runApp(
      new MaterialApp(
        builder: (context, child) => new SafeArea(
              child: new ColorDefinition(child: child),
            ),
        home: new FirstPage(),
      ),
    );

如果您使用继承的小部件,则不必担心要查看您推送的页面的弹出窗口,这将适用于基本用例,但最终可能会在更复杂的情况下出现问题。


1
投票

弹出上下文时可以传回dynamic result,然后当值为setState((){})时调用true,否则只是保持状态。

我已粘贴一些代码片段供您参考。

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

此致,Mahi


1
投票

有两件事,从中传递数据

  • 第1页到第2页 在第1页中使用它 // sending "Foo" from 1st Navigator.push(context, MaterialPageRoute(builder: (_) => Page2("Foo"))); 在第2页中使用它。 class Page2 extends StatelessWidget { final String string; Page2(this.string); // receiving "Foo" in 2nd ... }

  • 第2页到第1页 在第2页中使用它 // sending "Bar" from 2nd Navigator.pop(context, "Bar"); 在第1页中使用它,它与之前使用的相同,但几乎没有修改。 // receiving "Bar" in 1st String received = await Navigator.push(context, MaterialPageRoute(builder: (_) => Page2("Foo")));

0
投票

今天我遇到了同样的情况,但我设法以更简单的方式解决它,我刚刚定义了一个在第一个有状态类中使用的全局变量,当我导航到第二个有状态的小部件时,我让它更新全局的值变量,自动强制第一个小部件更新。这是一个例子(我写的很匆忙所以我没有放置脚手架或材料应用程序,我只是想说明我的观点):

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
投票

您可以使用pushReplacement并指定新路由

© www.soinside.com 2019 - 2024. All rights reserved.