Android onResume() method equivalent in Flutter
Asked Answered
Q

4

52

I am working on a Flutter app and need to pop the screen. I tried initState() method but no luck. initState() gets called when I open a class for the first time.

Do we have an equivalent of Android onResume() method in Flutter?

Any ideas?

Quartern answered 3/11, 2018 at 4:37 Comment(1)
None of the answers below provide an exact equivalent. I wrote an answer that covers all equivalent lifecycle events to iOS and Android. https://mcmap.net/q/159718/-flutter-exact-lifecycle-equivalents-to-onresume-onpause-on-android-and-viewwillappear-viewdiddisappear-on-iosCafeteria
F
89

You can use the WidgetsBindingObserver and check the AppLifeCycleState like this example:

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
    }
  }
}

Take in mind that It will called every time you open the app or go the background and return to the app. (if your widget is active)

If you just want a listener when your Widget is loaded for first time, you can listen using addPostFrameCallback, like this example:

class YourWidgetState extends State<YourWidget> {

  _onLayoutDone(_) {
    //do your stuff
  }

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

}

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

Update: Null safety compliance

Felsite answered 3/11, 2018 at 5:10 Comment(9)
Does addPostFrameCallback and LayoutBuilder's build() method receive the control/focus at the same time?Blackandblue
No, addPostFrameCallback is called after the first render of the tree.Felsite
Try adding ? for null-safety.... in WidgetsBinding.instance?.addObserver(this); and WidgetsBinding.instance?.removeObserver(this);Lelea
AppLifecycleState.resumed has different behavior for iOS and Android. On android its called only when we come from background to foreground (not on screen load). For iOS its called on screen load too. Is this intended?Diamagnetism
https://mcmap.net/q/159719/-how-to-check-when-my-widget-screen-comes-to-visibility-in-flutter-like-onresume-in-android you can check this for more detailAvatar
I just tried this approach on my stateful widget. Unlike onResume, it doesn't seem to get called when a new screen is popped from the stack and my widget comes back to focus.Honan
no it's only when you open a native view or you press home, you app is paused and you open you app againFelsite
It's not the equivalent of Android's onResume. The code above only gets triggered when an app goes in background and back.Scut
It's working for App level only. What if I wants it for specific screenBalikpapan
P
45

If you go to another page, then is called when you comeback

Navigator.push(
  context,
  MaterialPageRoute(
    builder: (context) => SecondPage(),
  ),
).then((value) {
  _refreshFirstPage();
});
Pinole answered 10/4, 2020 at 1:36 Comment(3)
This works great thanks. In my case, I had to force a state refresh when coming back from a pop event. I couldnt use a push event and had to use pop, which does not have a then method. So this worked perfectly.Gentilesse
If I can navigate to five different pages from page A, then I need to add _refreshFirstPage(); at 5 places. I wish there was a better way of doing this.Bindery
This is the best solution for my case. I need to refresh the main page after my app user come back from a detail page. She might have performed something on the detail page, which require some liitle part of the main page to be updated. I don't need real 'onResume' equivalent since there's nothing to update anyway, if my app user opened something other than my app's detail page.Glop
S
11

You can accomplish this by registering a didChangeAppLifecycleState observer:

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...
  }
}

See WidgetsBindingObserver for more information.

Slicer answered 3/11, 2018 at 5:12 Comment(0)
L
6

Use focus_detector more information can see visibility_detector

Get notified every time your widget appears or disappears from the screen.

Similar to onResume()/onPause() on Android and viewDidAppear()/viewDidDisappear() on iOS.

Focus Detector fires callbacks for you whenever something happens to take or give your widget focus. Such an event might be, for instance, the user:

Navigating to/from another screen;

Turning the device’s screen on/off while your widget is visible;

Switching to/from another app while your widget is visible;

Scrolling your widget in/out the screen;

@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(),
    );
Lording answered 13/10, 2021 at 8:37 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.