颤振 - 当页面出现时始终执行功能

时间:2017-10-31 02:48:47

标签: dart flutter

如果name()页面出现,我怎样才能运行Page1函数?

在转到Page2之前的下面的代码中,我执行了dispose() 已经在Page2内,如果单击Android的后退按钮或物理按钮,则不会执行函数name(),但如果单击'go to Page1'按钮,则会执行函数name()

name()出现时,您是否可以帮助我始终执行Page1功能?

enter image description here

import 'package:flutter/material.dart';

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

class MyApp extends StatelessWidget {  
  @override
  Widget build(BuildContext context) {
    return new MaterialApp(
      home: new MyHomePage(),
      routes: <String, WidgetBuilder> {
        '/page2': (BuildContext context) => new Page2(),
      },
    );
  }
}

class MyHomePage extends StatefulWidget {
  @override
  _MyHomePageState createState() => new _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  String nameScreen;

  String name() {
    return 'foo1';
  }

  @override
  void initState() {
    super.initState();
    this.nameScreen = name();

  }

  @override
  void dispose() {
    this.nameScreen = '';
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return new Scaffold(
      appBar: new AppBar(
        title: new Text('Page 1'),
        backgroundColor: new Color(0xFF26C6DA),
      ),
      body: new Center(
        child: new Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            new RaisedButton(
              child: const Text('go to Page2'),
              onPressed: () async {
                dispose();
                bool isLoggedIn = await Navigator.of(context).pushNamed('/page2');
                if (isLoggedIn) {
                  setState((){
                    this.nameScreen = name();
                  });
                }
              },
            ),            
            new Text(
              '$nameScreen',              
            ),
          ],
        ),
      ),
    );
  }
}

class Page2 extends StatelessWidget{
  @override
  Widget build(BuildContext context) {
    return new Scaffold( 
      appBar: new AppBar(
        title: new Text('Page 2'),
        backgroundColor: new Color(0xFFE57373)
      ),
      body: new Center(
        child: new Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            new RaisedButton(
              child: const Text('go back to Page1'),
              onPressed: () {
                Navigator.pop(context, true);
              }
            ),
          ],
        ),
      ),
    );
  }
}

4 个答案:

答案 0 :(得分:3)

如果您愿意dispose并稍后更改pop,则无需致电State,因为dispose将从树中删除当前对象,这并没有转化为你想要发展的逻辑。

您确实可以覆盖BackButton并将同一个Navigator.pop(context, result)调用传递给它。请查看以下示例我稍微调整了您的代码,以向您显示State字段的每个nameScreen之间的差异。我希望这会对你有所帮助。

enter image description here

class MyHomePage extends StatefulWidget {
  @override
  _MyHomePageState createState() => new _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  String nameScreen = "";

  String name() {
    return 'foo1';
  }

  @override
  void initState() {
    super.initState();
    this.nameScreen = "From initState";

  }

@override
void dipose(){
    super.dispose();
}

  @override
  Widget build(BuildContext context) {
    return new Scaffold(
      appBar: new AppBar(
        title: new Text('Page 1'),
        backgroundColor: new Color(0xFF26C6DA),
      ),
      body: new Center(
        child: new Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            new RaisedButton(
              child: const Text('go to Page2'),
              onPressed: () async {
                //dispose(); ///No need for dispose
                String result = await Navigator.of(context).pushNamed('/page2');

                  setState((){
                    this.nameScreen = result;
                  });

              },
            ),
            new Text(
              '$nameScreen',
            ),
          ],
        ),
      ),
    );
  }
}

class Page2 extends StatelessWidget{
  @override
  Widget build(BuildContext context) {
    return new Scaffold(
      appBar: new AppBar(
          leading: new IconButton(icon: new Icon(Icons.arrow_back), onPressed: ()async{
            Navigator.pop(context,"From BackButton");
          }),
          title: new Text('Page 2'),
          backgroundColor: new Color(0xFFE57373)
      ),
      body: new Center(
        child: new Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            new RaisedButton(
                child: const Text('go back to Page1'),
                onPressed: () {
                  Navigator.pop(context, "From RaisedButton");
                }
            ),
          ],
        ),
      ),
    );
  }

答案 1 :(得分:1)

您可以覆盖第二个屏幕上的“后退”按钮。

`WillPopScope(
    onWillPop: () {
       print('back pressed');
       Navigator.pop(context, "From BackButton");
       return true;
      },
    child: Scaffold(...)`

答案 2 :(得分:1)

一种方法是在导航器小部件上使用.whenComplete()方法。

假设您要从第一页转到第二页。在这里,您必须将functionThatSetsTheState作为指向代码导航部分的指针。

该函数看起来像这样,应该在一个有状态的小部件中。

void functionThatSetsTheState(){
 setState(() {});
}

您的OnPressedOnTapOnLongPress等导航代码。

Navigator.of(context).push(MaterialPageRoute(builder: (BuildContext context) => SecondPage())).whenComplete(() => {functionThatSetsTheState()});

答案 3 :(得分:0)

假设您要从第1页导航到第2页,并在第2页加载后立即执行第2页中的功能(用于在加载第2页时立即显示对话框):

您可以通过添加第2页的 initState didChangeDependencies 来实现:

 WidgetsBinding.instance.addPostFrameCallback((timeStamp) {
    // Function to execute
  });

如果您想在执行功能之前添加一些逻辑以添加条件,只需在页面1中推送一个参数即可:

Navigator.of(context).pushNamed("/page-2", arguments : true)

最后,第2页中的代码变为:

 _functionToExecute(){
  print("done");
  }
 @override
 void didChangeDependencies() {
 
  WidgetsBinding.instance.addPostFrameCallback((timeStamp) {
    if(ModalRoute.of(context).settings.arguments)
    _functionToExecute()
  });
 }