14

我遇到以下问题:我的 Flutter 应用使用 GoogleMap。地图最初加载得很好。但是,如果我将应用程序置于后台并稍后恢复,则地图将保持空白。Google 徽标仍然显示,就像未指定 API 密钥时一样。我的多边形叠加层也没有出现。

该行为不能可靠地重现。有时,应用程序在后台运行数小时后地图加载正常,有时地图在几分钟后为空白。到目前为止,我只在 Android 上看到过这种行为。

没有指示错误的特定日志输出。

任何想法如何解决/解决这个问题?

我在这里提出了一个截图问题:https ://github.com/flutter/flutter/issues/40284

编辑 1: 我能够使用 GoogleMap 作为根小部件来重现它,并且没有任何多边形/特征覆盖。此外,我发现在某些时候疯狂放大地图会“重新激活”地图(突然地图再次变得可见)。这可能是底层 Android Google Maps SDK 的已知问题吗?

编辑2: 我发现地图仍在反应(例如,点击/手势监听器仍然触发)。此外,地图并不是真正的空,它只是变得半透明,因此屏幕会显示地图后面的任何小部件。

4

6 回答 6

22

我发现如果您点击标记或更改地图重新渲染的样式

class TheWidgetThatHasTheMap with WidgetsBindingObserver {

   //...your code

    @override
    void didChangeAppLifecycleState(AppLifecycleState state) {
        if (state == AppLifecycleState.resumed) {
            controller.setMapStyle("[]");
        }
    }
}
于 2020-03-04T22:03:52.107 回答
3

不是核心问题的解决方案,但我能够通过创建插件项目的分支并修改 GoogleMapController.java 来解决此错误,如下所示:

@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());
    }
  }

现在,在每个恢复事件中,都会重新渲染地图。

于 2019-12-21T11:15:05.753 回答
2

在处理有状态的小部件时,将下面的代码放入您的代码中,如下所示

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("[]");
       }
    }
 }

然后您可以在状态小部件中添加以下代码

于 2021-10-13T10:26:43.203 回答
1

我尝试了一些东西,它似乎正在工作!

步骤01,为相关类的State类实现WidgetsBindingObserver如下,即:

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

步骤 02,覆盖didChangeAppLifecycleState方法,即:

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

步骤 03 为初始化状态添加这个

WidgetsBinding.instance!.addObserver(this);

Step 04 Step 4应该如下

//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;
    }
  }
于 2021-07-21T06:19:39.147 回答
0

另一个不需要分叉插件、构建等的临时修复。
添加一个已didChangeAppLifecycleState实现的 viaWidgetsBindingObserver到您的小部件,并通过状态更改使 GoogleMap 小部件重建。

于 2020-10-08T16:13:03.850 回答
0
   if you facing this problem in 2022 also  add this line above your class

类 YourClass 使用 WidgetsBindingObserver 扩展 StatefulWidget

Completer<GoogleMapController> controller = Completer();
    
          @override
            void dispose() {
    
              WidgetsBinding.instance!.removeObserver(this);
            
              super.dispose();
            }
              @override
              void didChangeAppLifecycleState(AppLifecycleState state) async {
                  super.didChangeAppLifecycleState(state);
                print('\n\ndidChangeAppLifecycleState');
             
                    if (state == AppLifecycleState.resumed) {
                        final GoogleMapController controller1 = await controller.future;
                        controller1.setMapStyle('[]');
                }
                
              }
        
        
          void initState() {                             
        
            super.initState();
              
            WidgetsBinding.instance!.addObserver(this);
          }
于 2022-01-19T12:31:59.203 回答