Flutter上的小部件的onResume()和onPause()

时间:2017-06-02 14:48:45

标签: android ios dart lifecycle flutter

现在,一个小部件只有initeState()在第一次创建小部件时被触发,而dispose()则在小部件被销毁时被触发。有没有一种方法来检测窗口小部件何时返回到前台?当一个小部件即将进入后台时,因为另一个小部件刚刚被推出? 这相当于onResume和onPause被触发为Android,viewWillAppear和viewWillDisappear为ios

5 个答案:

答案 0 :(得分:22)

有一个抽象类调用者WidgetsBindingObserver

https://docs.flutter.io/flutter/widgets/WidgetsBindingObserver-class.html

in

  @override
  void didChangeAppLifecycleState(AppLifecycleState state) {
    setState(() {
            _notification = state;
    });
  }

有“状态”,可以管理为

switch(state.index){
case 0:// resumed

break;
case 1:// inactive

break;
case 2:// paused

break;
}

答案 1 :(得分:9)

您最常见的情况是,如果您正在运行动画,并且您不想在后台使用资源。在这种情况下,您应该使用State扩展TickerProviderStateMixin并使用State作为vsync的{​​{1}}参数。当AnimationController可见时,Flutter将只负责调用动画控制器的听众。

如果您希望在StateState隐藏的PageRoute被其他内容遮挡时,您可以传递maintainState PageRoute参数{} {1}}到false构造函数。如果你这样做,你的PageRoute会在它被隐藏的时候重置自己(和它的孩子),并且必须使用作为构造函数参数传入的属性在State中重新构造它自己。 initState。如果您不想完全重置,可以使用模型或控制器类或PageStorage来保存用户的进度信息。

以下是演示这些概念的示例应用。

screen 1 screen 2 screen 3

widget

答案 2 :(得分:2)

我创建 visibility_aware_state 是为了让某些东西的行为类似于 Android 的 Activity.onResume()。它还考虑了弹出和推送导航。

class Example extends StatefulWidget {
  @override
  _ExampleState createState() => _ExampleState();
}

class _ExampleState extends VisibilityAwareState<Example> {
  @override
  Widget build(BuildContext context) {
    // return your widget
  }

  @override
  void onVisibilityChanged(WidgetVisibility visibility) {
    switch(visibility) {
      case WidgetVisibility.VISIBLE:
        // Like Android's Activity.onResume()
        break;
      case WidgetVisibility.INVISIBLE:
        // Like Android's Activity.onPause()
        break;
      case WidgetVisibility.GONE:
        // Like Android's Activity.onDestroy()
        break;
    }
    super.onVisibilityChanged(visibility);
  }
}

答案 3 :(得分:0)

我来晚了一些,但为那些将来可能会寻找它的人提供了完美的解决方案。 Navigator.push()实际上是未来。这意味着它具有then()回调函数。因此在您从第二个屏幕调用then()之后,将调用Navigator.pop()。甚至您也可以从第二个屏幕发送一些数据并在第一个屏幕中访问数据。

示例:

//from Screen A
Navigator.of(context).push(MaterialPageRoute(builder:(context)=>B()))
.then((value)=>{ refresh() });

//in Screen B with data
Navigator.pop(context,[1]);

//or without data
Navigator.pop(context);

因此refresh()将在屏幕A的简历上被调用。

答案 4 :(得分:-2)

这是一个完整的示例,演示如何正确处理事物,进行测试,按主屏幕按钮并恢复应用程序,您将看到didChangeAppLifecycleState被调用。

class HomePage extends StatefulWidget {
  @override
  _HomePageState createState() => _HomePageState();
}

class _HomePageState extends State<HomePage> with WidgetsBindingObserver {
  @override
  void initState() {
    super.initState();

    // add the observer
    WidgetsBinding.instance.addObserver(this);
  }

  @override
  void dispose() {
    // remove the observer
    WidgetsBinding.instance.removeObserver(this);

    super.dispose();
  }

  @override
  void didChangeAppLifecycleState(AppLifecycleState state) {
    super.didChangeAppLifecycleState(state);

    // These are the callbacks
    switch (state) {
      case AppLifecycleState.resumed:
        // widget is resumed
        break;
      case AppLifecycleState.inactive:
        // widget is inactive
        break;
      case AppLifecycleState.paused:
        // widget is paused
        break;
      case AppLifecycleState.detached:
        // widget is detached
        break;
    }
  }

  @override
  Widget build(BuildContext context) => Scaffold();
}