Flutter GoogleMap is blank after resuming from background

7,011

Solution 1

I discovered that if you tap a marker or change the style the map re-renders

class TheWidgetThatHasTheMap with WidgetsBindingObserver {

   //...your code

    @override
    void didChangeAppLifecycleState(AppLifecycleState state) {
        if (state == AppLifecycleState.resumed) {
            controller.setMapStyle("[]");
        }
    }
}

Solution 2

Not a solution to the core problem, but I was able to work around this bug by creating a fork of the plugins project and modifying GoogleMapController.java as follows:

@Override
  public void onActivityResumed(Activity activity) {
    if (disposed || activity.hashCode() != registrarActivityHashCode) {
      return;
    }
    mapView.onResume();
    // Workaround for https://github.com/flutter/flutter/issues/40284
    // This apparently forces a re-render of the map.
    if (googleMap != null) {
      googleMap.setMapType(googleMap.getMapType());
    }
  }

Now, on every resume event, the map will be re-rendered.

Solution 3

When dealing with a stateful widget, put the code below in your code as shown below

class MainScreenState extends State<MainScreen> with WidgetsBindingObserver 
 {....


  @override
  void initState() {
     super.initState();
     WidgetsBinding.instance!.addObserver(this);
     ...    // Other codes here 
  }


  @override
  void didChangeAppLifecycleState(AppLifecycleState state) {
       if (state == AppLifecycleState.resumed) {
         mapController!.setMapStyle("[]");
       }
    }
 }

Then you can add the code below in the state widget

Solution 4

I tried something & it seems to be working!

Step 01, Implement WidgetsBindingObserver for related class's State class as follows, i.e:

class MainScreenState extends State<MainScreen> with WidgetsBindingObserver {....

Step 02, Override didChangeAppLifecycleState method i.e:

@override
  Future<void> didChangeAppLifecycleState(AppLifecycleState state) async {
    super.didChangeAppLifecycleState(state);
    switch (state) {
      case AppLifecycleState.inactive:
        print('appLifeCycleState inactive');
        break;
      case AppLifecycleState.resumed:
        print('appLifeCycleState resumed');
        break;
      case AppLifecycleState.paused:
        print('appLifeCycleState paused');
        break;
      case AppLifecycleState.detached:
        print('appLifeCycleState detached');
        break;
    }
  }

Step 03 add this for init state

WidgetsBinding.instance!.addObserver(this);

Step 04 Step 4 should be as follows

//onMapCreated method
  void onMapCreated(GoogleMapController controller) {
    controller.setMapStyle(Utils.mapStyles);
    _controller.complete(controller);
  }
// lifecycle
  @override
  Future<void> didChangeAppLifecycleState(AppLifecycleState state) async {
    super.didChangeAppLifecycleState(state);
    switch (state) {
      case AppLifecycleState.inactive:
        print('appLifeCycleState inactive');
        break;
      case AppLifecycleState.resumed:
        **//Add These lines**
        final GoogleMapController controller = await _controller.future;
        onMapCreated(controller);
        print('appLifeCycleState resumed');
        break;
      case AppLifecycleState.paused:
        print('appLifeCycleState paused');
        break;
      case AppLifecycleState.detached:
        print('appLifeCycleState detached');
        break;
    }
  }
Share:
7,011
jbxbergdev
Author by

jbxbergdev

Freelance mobile developer based in Berlin.

Updated on December 16, 2022

Comments

  • jbxbergdev
    jbxbergdev over 1 year

    I'm experiencing the following issue: My Flutter app uses a GoogleMap. The map loads just fine initially. However, if I put the app into the background and resume a while later, the map stays blank. The Google logo still shows, like it happens when the API key isn't specified. My polygon overlay doesn't show up, either.

    The behavior is not reliably repruducable. Sometimes, the map loads fine after the app had been in the background for hours, sometimes the map is blank after minutes. So far, I have only seen this behavior on Android.

    There are no specific log outputs that indicate an error.

    Any ideas how to fix/work around this?

    I filed an issue with screenshot here: https://github.com/flutter/flutter/issues/40284

    EDIT 1: I was able to reproduce this with a GoogleMap as root widget and also without any polygon/feature overlay. Also, I found that wildly zooming in at some point 'reanimates' the map (suddenly the map becomes visible again). Is this maybe a known issue with the underlying Android Google Maps SDK?

    EDIT 2: I found that the map is still reacting (e.g. tap/gesture listeners still trigger). Also, the map isn't really empty, it just becomes translucent, so the screen displays whatever widget is behind the map.