Flutter - 页面出现时总是执行一个函数

raf*_*b21 4 dart flutter

name()每当Page1页面出现时,我怎样才能让函数运行?

在下面的代码中,如果我点击后退按钮或Android的物理按钮,Page2我会执行dispose() Already inside Page2,该功能name()不会执行,但如果我点击该'go to Page1'按钮,则该功能会name()被执行。

你能帮我name()Page1出现时总是执行这个功能吗?

在此处输入图片说明

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);
              }
            ),
          ],
        ),
      ),
    );
  }
}
Run Code Online (Sandbox Code Playgroud)

azi*_*iza 7

dispose当您愿意popState稍后更改时,根本不需要调用,因为dispose将从树中删除当前对象,这不会转换为您尝试开发的逻辑。

您确实可以覆盖BackButton并将相同的调用传递Navigator.pop(context, result)给它。检查下面的例子中,我已经优化了你的代码一点点向您展示每个之间的区别State你的nameScreen领域。我希望这可以帮助你。

在此处输入图片说明

class MyHomePage extends StatefulWidget {
  @override
  _MyHomePageState createState() => _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 Scaffold(
      appBar: AppBar(
        title: const Text('Page 1'),
        backgroundColor: Color(0xFF26C6DA),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            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;
                  });

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

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

  • 我绝对认为这是 Flutter 框架中缺少的主要功能。检测小部件何时重新成为焦点是一个明显的用例(例如,刷新来自某个远程源的数据)。类似于原生 Android 的 onResume 回调。 (4认同)
  • 解决这个问题的一种方法是我只是在 `setState` 顶部添加了 `if(result == null) {result = "Android back button";}`,以防用户使用物理 Android 按钮 (2认同)
  • 仅针对您提到的特定用例。您可以使用 StreamBuilder 来监听源上的更改并根据更改重新构建您的小部件 (2认同)

小智 5

执行此操作的一种方法是使用.whenComplete()导航器小部件上的方法。

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

该函数如下所示,并且应该位于 Stateful Widget 中。

void functionThatSetsTheState(){
    setState(() {});
}
Run Code Online (Sandbox Code Playgroud)

您的OnPressedOnTapOnLongPress等导航代码。

void functionThatSetsTheState(){
    setState(() {});
}
Run Code Online (Sandbox Code Playgroud)