【问题标题】:Flutter: how to keep widget with Google Map unchanged?Flutter:如何保持 Google Map 的小部件不变?
【发布时间】:2019-06-08 00:25:47
【问题描述】:

我正在使用Google Maps for Flutter 小部件。 在我的应用程序中,地图是通过 BottomNavigationBar 的选项卡之一显示的。

我有以下问题:

  1. 用户在地图标签上
  2. 用户更改选项卡(通过点击另一个选项卡)
  3. [问题] 当用户返回地图的选项卡时,地图会重绘。

我想在用户离开地图选项卡时保持地图原样,以便他稍后返回时可以继续使用它。

试图:

  • 使用 PageStorage - 没有成功。
  • 制作类似 Singletone of Map 状态的东西 - 没有成功。
  • 使用 AutomaticKeepAliveClientMixin (saw here),看起来很有希望,但仍然没有成功。

(我承认我可能做错了什么)

最后一次尝试的代码:

class MapScreen extends StatefulWidget {
  @override
  State<StatefulWidget> createState() => MapScreenState();
}

class MapScreenState extends State<MapScreen> with AutomaticKeepAliveClientMixin {
  GoogleMapController mapController;

  @override
  bool get wantKeepAlive => true;

  @override
  Widget build(BuildContext context) {
    super.build(context);
    return Scaffold(
        appBar: AppBar(
          title: const Text("Map"),
        ),
        body: GoogleMap(
          onMapCreated: _onMapCreated,
        )
    );
  }

  void _onMapCreated(GoogleMapController controller) {
      mapController = controller;
      updateKeepAlive();
  }
}

所以,我只需要一种方法来保持 MapScreen 处于活动状态并保持不变,或者以某种方式存储其状态并在用户返回 MapScreen 时恢复它。或者其他可以解决问题的方法。

【问题讨论】:

  • Diegos 回答的一些额外想法。您可以使用 Offstage 小部件,并在导航时将小部件移出屏幕并返回。我不知道 google_maps 插件,但您能否单独存储相机位置并将其包含在 google_maps 小部件中作为示例解决方法,如果这是每次重置并导致问题的原因。
  • @Ian 尝试了 Offstage 小部件,仍然是相同的行为。问题不仅在于相机位置,还在于加载地图所需的时间。我现在可能会存储相机位置(以及其他选项,如果需要),但如果我找到或提出解决方案,我会在这里发布。
  • 您已经找到解决方案了吗?我也面临这个问题。
  • 你有没有找到解决这个@AQRC的方法
  • @TheTokenizer 我完全停止了我的颤振项目的工作,所以答案是否定的,不幸的是我没有找到解决方案

标签: google-maps dart flutter


【解决方案1】:

使用IndexedStack

例如:

Class _ExamplePageState extends State<ExamplePage> {
  int _bottomNavIndex = 0;

  final List<Widget> _children = [
    WidgetOne(),
    WidgetTwo(),
    GoogleMap(),
  ]

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: IndexedStack(
        index: _bottomNavIndex,
        children: _children,
      ),
      bottomNavigationBar: BottomNavigationBar(
        currentIndex: _bottomNavIndex,
        onTap: (index) {
          if (_bottomNavIndex == index) return;
          setState(() {
            _bottomNavIndex = index;
          });
        }
        items: [ ... ]
      ),
    );
  }
}

【讨论】:

    【解决方案2】:

    Widget 总是在您从一个页面更改到另一个页面后重建,所以,试试这个,为GoogleMap 使用一个变量,如果它与 null 不同,则重新使用。

        GoogleMap _map;
    
         @override
        Widget build(BuildContext context) {
          if (_map == null){
            _map =  GoogleMap(
                onMapCreated: _onMapCreated,
              );
          }
          return Scaffold(
              appBar: AppBar(
                title: const Text("Map"),
              ),
              body:_map,
          );
        }
    

    【讨论】:

    • 试过这个,不幸的是,小部件不仅“重建”,而且通过在页面来回更改时调用createState()“重建其状态”来实现它,所以_map将永远是@987654326 @ on build 方法调用。还尝试了与createState() 相同的方法(如果它为空则创建状态,否则返回之前创建的状态),但它会导致框架中的断言错误。
    • 你在使用 AutomaticKeepAliveClientMixin 吗?
    • 是的,我是。甚至让 State 使用它,但它没有帮助。现在我将按照 Ian 的建议存储相机位置和所有其他数据。如果我找到或提出解决方案,我会在这里发布
    • 你是如何解决这个问题的?
    • AQRC,你找到解决办法了吗?
    【解决方案3】:

    我只是遇到了同样的问题,mixin 解决了它。我想你只是错过了在声明末尾输入 mixin 的类型。

    class MapScreenState extends State<MapScreen> with AutomaticKeepAliveClientMixin<MapScreenState>
    

    如果有的话,请参阅this 线程。

    【讨论】:

    • 这对我不起作用,您还有什么需要做的吗?你的设置是什么?
    猜你喜欢
    • 2020-01-17
    • 2011-01-28
    • 1970-01-01
    • 1970-01-01
    • 2018-12-06
    • 1970-01-01
    • 2016-07-09
    • 2021-05-24
    • 2019-07-11
    相关资源
    最近更新 更多