Flutter GoogleMap组件切换页面时残留残影问题求助
优化GoogleMap组件页面转场残影问题的方案
方案1:状态控制地图显示/占位容器切换
在页面State类中维护一个布尔变量,默认设为true。触发跳转时先将变量设为false并调用setState,延迟极短时间后执行页面跳转,让地图在转场前先被同尺寸的占位容器替代,避免残影。
示例代码:
bool _isMapVisible = true; void _goToNextPage() { setState(() { _isMapVisible = false; }); Future.delayed(const Duration(milliseconds: 100), () { Navigator.push(context, MaterialPageRoute(builder: (_) => NextPage())); }); } @override Widget build(BuildContext context) { return Scaffold( body: Column( children: [ Hero(tag: 'avatar', child: YourAvatarWidget()), _isMapVisible ? GoogleMap( onMapCreated: (controller) => myGoogleMapController.complete(controller), // 地图其他配置 ) : Container( width: double.infinity, height: 200, // 和地图组件保持一致高度 color: Theme.of(context).scaffoldBackgroundColor, ), // 页面其他组件 ], ), ); }
方案2:用Offstage组件快速隐藏地图
和方案1逻辑一致,但使用Offstage组件控制地图可见性,无需销毁重建地图组件,性能更优。跳转前将offstage设为true,延迟后执行跳转。
示例代码:
bool _hideMap = false; void _goToNextPage() { setState(() { _hideMap = true; }); Future.delayed(const Duration(milliseconds: 80), () { Navigator.push(context, MaterialPageRoute(builder: (_) => NextPage())); }); } @override Widget build(BuildContext context) { return Scaffold( body: Column( children: [ Hero(tag: 'avatar', child: YourAvatarWidget()), Offstage( offstage: _hideMap, child: GoogleMap( onMapCreated: (controller) => myGoogleMapController.complete(controller), // 地图其他配置 ), ), // 页面其他组件 ], ), ); }
方案3:监听路由生命周期处理地图
监听当前页面的路由移除事件,在页面即将被弹出时,先隐藏地图再完成路由操作,利用路由生命周期同步地图状态变化。
示例代码:
@override void initState() { super.initState(); ModalRoute.of(context)?.addScopedWillPopCallback(() async { setState(() { _isMapVisible = false; }); // 短暂等待地图隐藏后再允许路由跳转 await Future.delayed(const Duration(milliseconds: 50)); return true; }); }
方案4:自定义页面转场动画
改用覆盖式的转场动画(如从底部滑入),让新页面快速覆盖原页面的地图区域,直接掩盖残影问题。
示例代码:
Navigator.push( context, PageRouteBuilder( pageBuilder: (_, animation, __) => NextPage(), transitionsBuilder: (_, animation, __, child) { final tween = Tween(begin: const Offset(0.0, 1.0), end: Offset.zero) .chain(CurveTween(curve: Curves.easeOut)); return SlideTransition( position: animation.drive(tween), child: child, ); }, ), );
内容的提问来源于stack exchange,提问作者Sam
相关产品推荐
相关产品推荐

