在弹出导航上刷新另一个类的状态

时间:2020-01-22 04:19:42

标签: flutter

我有一个应用程序,该应用程序在一个类中包含一个支架,而在另一个类中包含该窗口小部件的主体。支架上的按钮之一会打开一个设置菜单,以更改显示设置。由于此按钮位于脚手架上,并且主体位于另一个类中,因此从设置菜单返回后,我无法使主体重置其状态并进行重建。我应该如何从ScaffoldCalc类中告诉LocalCalculator类为setState?

class _ScaffoldCalcState extends State<ScaffoldCalc> {

  @override
  void initState() {
    super.initState();
    checkDisclaimer();
  }

  @override
  Widget build(BuildContext context) {
    return Stack(
      children: <Widget>[
        ExcludeSemantics(
          excluding: showCalcDisclaimer,
          child:Scaffold(
            appBar: AppBar(
                title: const Text('Local Anesthetic Calculator'),
                backgroundColor: MyColors.PrimaryColor1,
                centerTitle: false,
                elevation: 0,
                actions: <Widget>[
                  IconButton(
                    icon: Icon(Icons.settings, semanticLabel: "Settings Menu",),
                    onPressed: () {
                      AutoOrientation.fullAutoMode();
                      Navigator.push(
                        context,
                        MaterialPageRoute(builder: (context) => SettingsMenu()),
                      ).then((value) {
                        //Run after return from settings
                        AutoOrientation.portraitAutoMode();
                      });
                    },
                  ),
                ]
            ),
            body: LocalCalculator(),
          ),
        ),
      ],
    );
  }
}


class LocalCalculator extends StatefulWidget {
  @override
  State<StatefulWidget> createState() {
    return _LACalcState();
  }
}

class _LACalcState extends State<LocalCalculator> with TickerProviderStateMixin{

 @override
  void initState() {
    super.initState();
    AutoOrientation.portraitAutoMode();
    WidgetsBinding.instance.addPostFrameCallback(_afterLayout);
  }

  //Build our widget tree
  @override
  Widget build(BuildContext context) {
    return Material(
      child: GestureDetector(
        behavior: HitTestBehavior.translucent,
        onTap: () {
          FocusScope.of(context).requestFocus(new FocusNode());
          bupivacaine.hideEditing();
          ropivacaine.hideEditing();
          mepivacaine.hideEditing();
          lidocaine.hideEditing();
          chloroprocaine.hideEditing();
        },
        child: Column(
          mainAxisSize: MainAxisSize.min,
          children: <Widget>[
            //CalcHeader(),
            WeightDisplay(),
            DrugCardHeader(),
            DrugCardList(),
          ],
        ),
      ),
    );
  }
}

2 个答案:

答案 0 :(得分:0)

当您需要更改任何小部件时,例如整个应用, 完成某些任务后,我们不得不刷新应用程序。

使用setState(),setState()刷新小部件的整个状态,并 作为代码,您可以在 Navigator Then 之后输入setState。

setState重建您的身体并重新加载所有小部件。

Navigator.push(
context,
MaterialPageRoute(builder: (context) => SettingsMenu()))
.then((value) {
  //Run after return from settings
  setState(() {});
  AutoOrientation.portraitAutoMode();
});

答案 1 :(得分:0)

虽然 setState 对于在有状态的小部件类中管理状态非常有用,但是当尝试在多个小部件类之间共享公共状态时,可以使用更好的状态管理方法,例如provider

Flutter负责在状态改变时重新加载所有具有更新后值的小部件(使用此状态)。详情请参阅state management demo

检查此示例代码,以扩展提供者的支持,以管理Settings页内的计数器的状态以及在LocalCalculator页中正在更新的值。

不要忘记在主类的runApp方法中绑定提供程序 MyProvider

class ScaffoldCalc extends StatefulWidget {
  @override
  State<StatefulWidget> createState() {
    return _ScaffoldCalcState();
  }
}

class _ScaffoldCalcState extends State<ScaffoldCalc> {

  @override
  void initState() {
    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    return Stack(
      children: <Widget>[
        ExcludeSemantics(
          excluding: false,
          child:Scaffold(
            appBar: AppBar(
                title: const Text('Local Anesthetic Calculator'),
                backgroundColor: Colors.blue,
                centerTitle: false,
                elevation: 0,
                actions: <Widget>[
                  IconButton(
                    icon: Icon(Icons.settings, semanticLabel: "Settings Menu",),
                    onPressed: () {
                      Navigator.push(
                        context,
                        MaterialPageRoute(builder: (context) => SettingsPage()),
                      ).then((value) {
                        //Run after return from settings
                      });
                    },
                  ),
                ]
            ),
            body: LocalCalculator(),
          ),
        ),
      ],
    );
  }
}

class SettingsPage extends StatefulWidget {
  @override
  State<StatefulWidget> createState() {
    return _SettingsPageState();
  }

}

class _SettingsPageState extends State<SettingsPage> {

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text("New page"),),
      floatingActionButton: Wrap(
        direction: Axis.vertical,
        spacing: 10.0,
        children: <Widget>[
          FloatingActionButton(
            heroTag: "fab-add",
            backgroundColor: Colors.green,
            child: Icon(Icons.add),
            onPressed: (){
              Provider.of<MyProvider>(context,listen: false).increment();
            },
          ),
          FloatingActionButton(
            heroTag: "fab-subtract",
            backgroundColor: Colors.red,
            child: Icon(Icons.remove),
            onPressed: (){
              Provider.of<MyProvider>(context,listen: false).decrement();
            },
          ),
        ],
      ),
    );
  }

}

class MyProvider extends ChangeNotifier {
  double state = 1.0;

  void increment() {
    state += 1;
    notifyListeners();
  }

  void decrement() {
    state -= 1;
    notifyListeners();
  }

}

class LocalCalculator extends StatefulWidget {
  @override
  State<StatefulWidget> createState() {
    return _LACalcState();
  }
}

class _LACalcState extends State<LocalCalculator> with TickerProviderStateMixin{

  @override
  void initState() {
    super.initState();
  }

  @override
  void didChangeDependencies() {
    super.didChangeDependencies();
  }

  //Build our widget tree
  @override
  Widget build(BuildContext context) {
    return Material(
      child: GestureDetector(
        behavior: HitTestBehavior.translucent,
        onTap: () {
          FocusScope.of(context).requestFocus(new FocusNode());
        },
        child: Center(
          child: Text("Count is : ${Provider.of<MyProvider>(context).state}"),
        ),
      ),
    );
  }
}