Flutter中与Android的onResume()方法相当的方法是什么?

51

我正在开发一个Flutter应用程序,需要弹出屏幕。我尝试了initState()方法,但没有成功。当我第一次打开一个类时,initState()会被调用。

在Flutter中是否有与Android的onResume()方法相当的方法?

有什么想法吗?


1
以下没有一个答案提供了一个完全等价的解决方案。我写了一个回答,涵盖了所有与iOS和Android相当的生命周期事件。https://dev59.com/msPra4cB1Zd3GeqPoMi_#71279848 - Kyle Venn
4个回答

83
您可以使用WidgetsBindingObserver并像以下示例中那样检查AppLifeCycleState
class YourWidgetState extends State<YourWidget> with WidgetsBindingObserver {

  @override
  void initState() {
    WidgetsBinding.instance?.addObserver(this);
    super.initState();
  }

 
  @override
  void dispose() {
    WidgetsBinding.instance?.removeObserver(this);
    super.dispose();
  }
  

  @override
  void didChangeAppLifecycleState(AppLifecycleState state) {
    if (state == AppLifecycleState.resumed) {
       //do your stuff
    }
  }
}

请记住,如果您的小部件处于活动状态,每次打开应用程序或进入后台并返回应用程序时都会调用它。

如果您只想在小部件首次加载时侦听,请使用addPostFrameCallback进行侦听,如此示例:

class YourWidgetState extends State<YourWidget> {

  _onLayoutDone(_) {
    //do your stuff
  }

  @override
  void initState() {
    WidgetsBinding.instance?.addPostFrameCallback(_onLayoutDone);
    super.initState();
  } 

}

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

更新: 空安全合规性


尝试在 WidgetsBinding.instance?.addObserver(this);WidgetsBinding.instance?.removeObserver(this); 中添加 ? 来实现空安全。 - kosiara - Bartosz Kosarzycki
1
AppLifecycleState.resumed 在 iOS 和 Android 上有不同的行为。在 Android 上,仅在从后台返回前台时调用它(而不是屏幕加载时)。对于 iOS,它还会在屏幕加载时调用。这是预期的吗? - Uzair Aslam
您可以查看此链接以获取更多详细信息:https://dev59.com/-lMH5IYBdhLWcg3w3Ebb#58504433 - Amit
我刚刚在我的有状态小部件上尝试了这种方法。与 onResume 不同的是,当从堆栈中弹出一个新屏幕并且我的小部件重新获得焦点时,它似乎不会被调用。 - Harsha
这不等同于Android的onResume。上面的代码只在应用程序进入后台并返回时触发。 - idk.the.name
显示剩余3条评论

44
如果您前往另一页,那么当您回来时会调用“then”。
Navigator.push(
  context,
  MaterialPageRoute(
    builder: (context) => SecondPage(),
  ),
).then((value) {
  _refreshFirstPage();
});

2
这个很好用,谢谢。在我的情况下,当从弹出事件返回时,我不得不强制进行状态刷新。我无法使用推送事件,而必须使用pop,它没有then方法。所以这个完美地解决了问题。 - Janpan
3
如果我可以从页面A导航到五个不同的页面,那么我需要在5个地方添加"_refreshFirstPage();"。我希望有更好的方法来处理这个问题。 - Rohan Taneja
这是我情况下的最佳解决方案。当我的应用用户从详细页面返回时,我需要刷新主页面。她可能在详细页面上执行了某些操作,需要更新主页面的一小部分。我不需要真正的“onResume”等效,因为如果我的应用用户打开的是其他应用程序的详细页面,则无需更新任何内容。 - Daniel Wu

12

您可以通过注册didChangeAppLifecycleState观察器来实现此操作:

class _MyAppState extends State<MyApp> with WidgetsBindingObserver {
  @override
  void initState() {
    super.initState();
    WidgetsBinding.instance.addObserver(this);
  }

  @override
  void dispose() {
    WidgetsBinding.instance.removeObserver(this);
    super.dispose();
  }

  @override
  void didChangeAppLifecycleState(final AppLifecycleState state) {
    if (state == AppLifecycleState.resumed) {
      setState(() {
        // ...your code goes here...
      });
    }
  }

  @override
  Widget build(final BuildContext context) {
    // ...your code goes here...
  }
}

更多信息请参见WidgetsBindingObserver


6

使用focus_detector。更多信息请参见visibility_detector

每当您的小部件出现或从屏幕中消失时,都会收到通知。

类似于Android上的onResume() / onPause()和iOS上的viewDidAppear() / viewDidDisappear()。

焦点检测器会在某些情况下为您触发回调,例如:

导航到/从其他屏幕;

在您的小部件可见时打开/关闭设备屏幕;

在您的小部件可见时切换到/从另一个应用程序;

将您的小部件滚动进/出屏幕;

@override
Widget build(BuildContext context) =>
    FocusDetector(
      onFocusLost: () {
        logger.i(
          'Focus Lost.'
          '\nTriggered when either [onVisibilityLost] or [onForegroundLost] '
          'is called.'
          '\nEquivalent to onPause() on Android or viewDidDisappear() on iOS.',
        );
      },
      onFocusGained: () {
        logger.i(
          'Focus Gained.'
          '\nTriggered when either [onVisibilityGained] or [onForegroundGained] '
          'is called.'
          '\nEquivalent to onResume() on Android or viewDidAppear() on iOS.',
        );
      },
      onVisibilityLost: () {
        logger.i(
          'Visibility Lost.'
          '\nIt means the widget is no longer visible within your app.',
        );
      },
      onVisibilityGained: () {
        logger.i(
          'Visibility Gained.'
          '\nIt means the widget is now visible within your app.',
        );
      },
      onForegroundLost: () {
        logger.i(
          'Foreground Lost.'
          '\nIt means, for example, that the user sent your app to the background by opening '
          'another app or turned off the device\'s screen while your '
          'widget was visible.',
        );
      },
      onForegroundGained: () {
        logger.i(
          'Foreground Gained.'
          '\nIt means, for example, that the user switched back to your app or turned the '
          'device\'s screen back on while your widget was visible.',
        );
      },
      child: Container(),
    );

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接