从后台恢复后,Flutter GoogleMap 为空白
Posted
技术标签:
【中文标题】从后台恢复后,Flutter GoogleMap 为空白【英文标题】:Flutter GoogleMap is blank after resuming from background 【发布时间】:2020-04-09 22:37:39 【问题描述】:我遇到了以下问题:我的 Flutter 应用使用了 GoogleMap。地图最初加载得很好。但是,如果我将应用程序置于后台并稍后恢复,则地图将保持空白。 Google 徽标仍然显示,就像未指定 API 密钥时一样。我的多边形叠加层也没有显示出来。
该行为不能可靠地重现。有时,应用程序在后台运行数小时后地图加载正常,有时地图在几分钟后为空白。到目前为止,我只在 android 上看到过这种行为。
没有指示错误的特定日志输出。
任何想法如何解决/解决这个问题?
我在这里提交了一个截图问题:https://github.com/flutter/flutter/issues/40284
编辑 1: 我能够使用 GoogleMap 作为根小部件来重现这一点,并且也没有任何多边形/特征覆盖。此外,我发现在某些时候疯狂放大地图会“重新激活”地图(突然地图再次变得可见)。这可能是底层 Android Google Maps SDK 的已知问题吗?
编辑 2: 我发现地图仍在反应(例如,点击/手势侦听器仍会触发)。此外,地图并不是真正的空,它只是变得半透明,因此屏幕会显示地图后面的任何小部件。
【问题讨论】:
这可能是个愚蠢的问题,但你能缩小地图吗?从截图看来是放大到了“地面”级别。 没有愚蠢的问题。 :-) 是的,它尝试了缩放,但它不起作用。此外,底图是卫星地图,因此至少会显示一些颜色。 【参考方案1】:不是核心问题的解决方案,但我能够通过创建插件项目的分支并如下修改 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());
现在,在每个恢复事件中,地图都会重新渲染。
【讨论】:
此解决方案工作了一段时间,然后将应用程序设置为 for 和 background 几次后,问题再次出现【参考方案2】:我发现如果您点击标记或更改地图重新渲染的样式
class TheWidgetThatHasTheMap with WidgetsBindingObserver
//...your code
@override
void didChangeAppLifecycleState(AppLifecycleState state)
if (state == AppLifecycleState.resumed)
controller.setMapStyle("[]");
【讨论】:
我尝试在onMapCreated
中使用GoogleMapController
控制器,但它没有setMapStyle
方法
@kashlo 如果你的控制器被定义为 Completer另一个不需要分叉插件、构建等的临时修复。
将通过WidgetsBindingObserver
实现的didChangeAppLifecycleState
添加到您的小部件,并使GoogleMap 小部件通过状态更改重建。
【讨论】:
【参考方案4】:我尝试了一些东西,它似乎正在工作!
步骤 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);
步骤 04 第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;
【讨论】:
谢谢....你有使用Flutter Hooks
的例子吗?
没有,但是这个链接有。 medium.com/flutter-community/…【参考方案5】:
在处理有状态的小部件时,将下面的代码放在你的代码中,如下所示
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("[]");
然后你可以在状态小部件中添加下面的代码
【讨论】:
以上是关于从后台恢复后,Flutter GoogleMap 为空白的主要内容,如果未能解决你的问题,请参考以下文章
Flutter GoogleMap Provider Context问题
Flutter中如何在PageView中正确使用GoogleMap
GoogleMap,如何在单击 Market en Flutter 时删除图标