Flutter Web: How to detect AppLifeCycleState changes
Asked Answered
N

2

4

I tested out the AppLifeCycleState on flutter web and it didn't work while it worked on mobile platforms.

This is an issue that is being worked on.

I was wondering if anyone knew any workarounds or packages which could do this?

Nickelous answered 13/7, 2021 at 18:36 Comment(0)
B
13

Here is my workaround

import 'dart:html';
import 'package:flutter/foundation.dart';

  // inside your State class

  @override
  void initState() {
    super.initState();
    if (kIsWeb) {
      window.addEventListener('focus', onFocus);
      window.addEventListener('blur', onBlur);
    } else {
      WidgetsBinding.instance!.addObserver(this);
    }
  }

  @override
  void dispose() {
    if (kIsWeb) {
      window.removeEventListener('focus', onFocus);
      window.removeEventListener('blur', onBlur);
    } else {
      WidgetsBinding.instance!.removeObserver(this);
    }
    super.dispose();
  }

  void onFocus(Event e) {
    didChangeAppLifecycleState(AppLifecycleState.resumed);
  }

  void onBlur(Event e) {
    didChangeAppLifecycleState(AppLifecycleState.paused);
  }

  @override
  void didChangeAppLifecycleState(AppLifecycleState state) {
    // do your thing
  }

Basically you hook into the browser's visibility API and invoke the life cycle callback yourself.

See also How to detect if flutter website is running in the background of browser?

Bourbon answered 14/7, 2021 at 16:57 Comment(13)
Hello, thanks for the help. What is the onVisbilityChange?Nickelous
Sorry, I didn't extend the class with WidgetsBindingObserver the errors are gone. I'll test it now.Nickelous
Hello, this works if I change tabs, is there a way I can also update the app life cycle state when the browser is out of focus? Thanks!Nickelous
Just like above but you hook into the browser's focus API insteadBourbon
May you please provide a code example? I tried doing it but couldn't figure it out.Nickelous
Also, in the code above, the code doesn't dispose properly and didChangeAppLifecycleState() still runs.Nickelous
I've edited the answer. Also, yes this is a known issue with flutter hot restart.Bourbon
Do I replace the window.addEventListener('visibilitychange', onVisibilityChange); with what you edited in your answer? Thanks for the help!Nickelous
Calling the dispose method normally (by popping the route) still doesn't work.Nickelous
Yeah, as I commented in the github issue, the best I can do is to make the listeners static, and then it does work. Let me know if you find a better way.Bourbon
Where do you add the static modifier?Nickelous
static void onFocus(Event e) { ... }. The catch is you can't call didChangeAppLifecycleState now because that's non-static. You'll have to work around thatBourbon
Oh ok thanks. I worked around the dispose not working by making a Boolean variable and then in the onFocus() and onBlur() I add an if check. It looks something like if (active) {...}. That seemed to fix the problem for me without having to make the methods static so that I don't have to work around the problem of not being able to call didChangeAppLifecycleState. That seemed to fix the dispose issue but also works when hot restarting. I think it's a better fix than the static with the only problem being that it leaks memory and might not be very performant on larger scale apps.Nickelous
S
0

Additionally, there is a flutter package that detects if Web app is refreshed or reloaded. You can take a look at flutterwebapp_reload_detector

Strophic answered 16/6 at 9:9 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.