You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Flutter中Huawei Maps不响应Offstage隐藏、Stack层级异常问题

问题背景

应用原有地图功能基于Google Maps实现,运行逻辑全部正常。为上架AppGallery替换为Huawei Maps做同等功能实现后,出现两类Google Maps上不存在的异常:

  • 使用Offstage、Opacity组件设置地图隐藏均失效,地图在Stack布局中无法按预期隐藏,异常效果如下:
    Huawei Maps隐藏失效异常截图
  • 多组件堆叠场景下,地图本应位于其他组件下层,实际会悬浮在所有组件最上层。

复现代码

页面布局逻辑

return Builder(
  builder: (context) {
    bContext = context;
    widget.firstLoad = false;
    googleMapKey = GlobalKey<GoogleMapDrawerState>(
        debugLabel: 'googleMapWidget');
    Provider.of<ControllerProvider>(context, listen: false)
        .loadGoogleMapKey(googleMapKey);
    var googleMap = GoogleMapDrawer(
        key: googleMapKey,
        mapCompleted: (controller) {
          Provider.of<ControllerProvider>(context, listen: false)
              .loadController(controller);
          if (Theme.of(context).brightness == Brightness.dark) {
            Provider.of<ControllerProvider>(context, listen: false)
                .changeTheme(Brightness.dark);
          }
        },
        markers:
            Provider.of<ControllerProvider>(context, listen: false)
                        .marker !=
                    null
                ? [
                    Provider.of<ControllerProvider>(context,
                            listen: false)
                        .marker
                  ]
                : [],
        cameraPosition: hm.CameraPosition(
            target: hm.LatLng(53.00825 + 0.004, 18.59762), zoom: 15));
    return Scaffold(
      body: Stack(children: [
        Offstage(
          offstage: true,
          child: googleMap,
        ),

自定义地图封装组件

代码中注释段为原Google Maps实现,和Huawei Maps调用逻辑完全一致:

return SizedBox(
  height: size.height * 0.51,
  width: size.width,
  child: /*GoogleMap(
      initialCameraPosition: widget.cameraPosition!,
      markers: markers != null ? Set.from(markers) : <Marker>{},
      onMapCreated: (controller) {
        Provider.of<ControllerProvider>(context, listen: false)
            .currentMapBrightness = Theme.of(context).brightness;
        widget.mapCompleted(controller);
      })*/
      HuaweiMap(
          initialCameraPosition: widget.cameraPosition!,
          markers: markers != null ? Set.from(markers) : <Marker>{},
          onMapCreated: (controller) {
            Provider.of<ControllerProvider>(context, listen: false)
                .currentMapBrightness = Theme.of(context).brightness;
                widget.mapCompleted(controller);
          },
      )
);
问题原因

这是Flutter平台原生视图渲染模式差异导致的,和业务代码逻辑无关:

  • Google Maps Flutter插件默认采用Texture接入模式渲染,地图内容直接绘制在Flutter的渲染纹理上,完全遵循Flutter组件树的层级、显隐、透明度规则,所以所有布局控制都能正常生效。
  • Huawei Maps Flutter插件在Android端默认采用SurfaceView作为原生视图渲染载体,SurfaceView的渲染窗口独立于Flutter的UI渲染树,不受Flutter框架的Offstage、Opacity、Stack层级规则约束,会默认悬浮在所有Flutter组件的最上层,直接导致隐藏失效、层级错乱问题。
修复方案

按优先级推荐以下3种可落地的解决方式:

  • 修改华为地图渲染模式(优先推荐)
    在HuaweiMap组件初始化时新增参数,将Android端默认的Surface渲染模式改为Texture渲染模式,修改后地图行为和Google Maps完全一致,所有布局控制规则正常生效,且无明显性能损耗:
    HuaweiMap(
      // 新增渲染模式配置
      androidRenderMode: AndroidRenderMode.texture,
      initialCameraPosition: widget.cameraPosition!,
      markers: markers != null ? Set.from(markers) : <Marker>{},
      onMapCreated: (controller) {
        Provider.of<ControllerProvider>(context, listen: false)
            .currentMapBrightness = Theme.of(context).brightness;
        widget.mapCompleted(controller);
      },
    )
    
  • 调整显隐逻辑为条件渲染
    如果不需要保留地图交互状态(比如不需要记住用户缩放、拖动的位置),直接放弃Offstage/Opacity的隐式控制,用条件判断直接在需要隐藏时把地图从组件树中移除,从根源上避免SurfaceView悬浮:
    // 替换原有Offstage包裹逻辑
    offstage ? SizedBox() : googleMap
    
  • 层级问题临时兼容
    如果仅需要解决地图悬浮在其他组件上层的问题、不需要控制透明度/显隐,可以给HuaweiMap外层包裹一层ClipRect组件,同时确保Stack中需要显示在地图上层的组件,在children列表中排在地图组件之后,即可临时修复层级错乱问题,但该方案对Offstage、Opacity的适配稳定性不如前两种方案。

内容的提问来源于stack exchange,提问作者Karol Wiśniewski

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.28 20:09:10