目前,小部件只有initeState()和Dispose(),前者在第一次创建小部件时被触发,后者在小部件被销毁时被触发.有没有一种方法可以检测到小部件何时返回前台?当一个小部件即将转到后台时,因为另一个小部件刚刚被放在前台呢? 相当于Android触发onResume和onPause,iOS触发viewWillAppear和viewWillDisplay

推荐答案

最常见的情况是,如果您正在运行动画,并且不想在后台消耗资源,则需要执行此操作.在这种情况下,您应该用TickerProviderStateMixin来扩展您的State,并使用您的State作为AnimationControllervsync参数.当State可见时,Flutter 将仅负责调用动画控制器的侦听器.

如果您希望在PageRoute被其他内容遮挡时处理PageRoute中的State,可以将falsemaintainState参数传递给PageRoute构造函数.如果这样做,State将在隐藏时重置自身(及其子对象),并且必须在initState中使用作为构造函数参数传递给其widget的属性重新构造自身.如果不想完全重置,可以使用模型或控制器类或PageStorage来保存用户的进度信息.

下面是一个示例应用程序,演示了这些概念.

screen 1

import 'package:flutter/material.dart';

void main() {
  runApp(new MaterialApp(
    onGenerateRoute: (RouteSettings settings) {
      if (settings.name == '/') {
        return new MaterialPageRoute<Null>(
          settings: settings,
          builder: (_) => new MyApp(),
          maintainState: false,
        );
      }
      return null;
    }
  ));
}

class MyApp extends StatefulWidget {
  MyAppState createState() => new MyAppState();
}

class MyAppState extends State<MyApp> with TickerProviderStateMixin {
  AnimationController _controller;

  @override
  void initState() {
    print("initState was called");
    _controller = new AnimationController(vsync: this)
      ..repeat(min: 0.0, max: 1.0, period: const Duration(seconds: 1))
      ..addListener(() {
        print('animation value ${_controller.value}');
      });
    super.initState();
  }

  @override
  void dispose() {
    print("dispose was called");
    _controller.dispose();
    super.dispose();
  }

  int _counter = 0;

  @override
  Widget build(BuildContext context) {
    return new Scaffold(
      appBar: new AppBar(
        title: new Text('home screen')
      ),
      body: new Center(
        child: new RaisedButton(
          onPressed: () {
            setState(() {
              _counter++;
            });
          },
          child: new Text('Button pressed $_counter times'),
        ),
      ),
      floatingActionButton: new FloatingActionButton(
        child: new Icon(Icons.remove_red_eye),
        onPressed: () {
          Navigator.push(context, new MaterialPageRoute(
            builder: (BuildContext context) {
              return new MySecondPage(counter: _counter);
            },
          ));
        },
      ),
    );
  }
}

class MySecondPage extends StatelessWidget {
  MySecondPage({ this.counter });

  final int counter;

  Widget build(BuildContext context) {
    return new Scaffold(
      appBar: new AppBar(
        title: new Text('Certificate of achievement'),
      ),
      body: new Column(
        crossAxisAlignment: CrossAxisAlignment.stretch,
        mainAxisAlignment: MainAxisAlignment.spaceAround,
        children: [
          new Icon(Icons.developer_mode, size: 200.0),
          new Text(
            'Congrats, you clicked $counter times.',
            style: Theme.of(context).textTheme.title,
            textAlign: TextAlign.center,
          ),
          new Text(
            'All your progress has now been lost.',
            style: Theme.of(context).textTheme.subhead,
            textAlign: TextAlign.center,
          ),
        ],
      ),
    );
  }
}

Flutter相关问答推荐

在Flutter中,CachedNetworks Image不工作(不从CachedData加载)

Flutter ReorderableListView在可滚动父级中无法完美工作

允许冻结在初始化时使用工厂

使用Future函数的容器中未显示图像,但在使用图像小工具时显示

在背景图像上排列定位徽标

在Flutter 小部件测试中找不到框中的AssetImage装饰

从Firestore流式传输单个文档还是整个集合更好?

了解多Provider 和流

在 flutter 的列中使用 Expanded 时出现渲染 Flex 错误

如何在 VS Code 中启用 Flutter 运行/调试工具栏?

创建混合 TextWidget 和 TextFieldWidget

如何在 GridView.builder 中设置 textform 字段并在 flutter 中将 12 个 textformfield 作为单个字符串获取?

状况不佳 - Cubit

flutter - 无法解析 JSON 消息:文档为空

无法将参数类型Future Function(String?)分配给参数类型void Function(NotificationResponse)?

使用 onPressed 切换到另一个屏幕无法正常工作

如何在dart中编写多个条件?

Flutter:整个判断整个应用生命周期的通用类

如何从我的Flutter 项目中删除错误?

如何使用我拥有的 .jks 文件签署我的应用程序