【问题标题】:Flutter: How do I update markers' position in google map using Getx Obx?Flutter:如何使用 Getx Obx 更新标记在谷歌地图中的位置?
【发布时间】:2021-12-27 15:09:29
【问题描述】:

我有关注view

import 'dart:async';
import 'package:get/get.dart';
import 'package:flutter/material.dart';
import 'package:google_maps_flutter/google_maps_flutter.dart';
import '../../Controllers/mapview_controller.dart';

class MapViewerPage extends StatelessWidget {
  MapViewerPage({Key? key}) : super(key: key);

  final MapViewController mapcontroller = MapViewController();
  final Completer<GoogleMapController> _controller = Completer();
  final CameraPosition _initialCameraPosition = const CameraPosition(
    target: LatLng(28.527582, 77.0688971),
    zoom: 16,
  );

  final BitmapDescriptor defaultIcon =
      BitmapDescriptor.defaultMarkerWithHue(BitmapDescriptor.hueRed);

  final List<Marker> allMarkers = [];

  @override
  Widget build(BuildContext context) {
    return GetBuilder<MapViewController>(
        init: mapcontroller,
        builder: (controller) {
           return SizedBox(
              width: double.infinity,
              height: double.infinity,
              child: Obx(() => GoogleMap(
            myLocationButtonEnabled: true,
            markers:Set<Marker>.of(allMarkers),
            mapType: MapType.normal,
            initialCameraPosition: _initialCameraPosition,
            onMapCreated: (GoogleMapController gmcontroller) {
              _controller.complete(gmcontroller);
              gmcontroller.setMapStyle(controller.loadMapStyle());
            },
          )),
            ),
        });
  }

  getMarkers() {
    //get markers from controller
    var realdata = mapcontroller.realtimeList;

    realdata.asMap().forEach((key, value) {
      var _marker = Marker(
          consumeTapEvents: true,
          markerId: MarkerId(key.toString()),
          position: LatLng(
              double.parse(value.latitude), double.parse(value.longitude)),
          onTap: () {
            //do something here
          });

      allMarkers.add(_marker);
    });
  }
}

我的控制器看起来像这样。

import 'package:flutter/services.dart';
import 'package:get/get.dart';
import '../../Models/model_realtime.dart';
import '../../Providers/common_api_provider.dart';

class MapViewController extends GetxController {
  var isLoading = false.obs;
  var realtimeList = <ModelRealtime>[].obs;

  @override
  void onInit() {
    fetchRealtimeData();
    super.onInit();
  }

  void fetchRealtimeData() async {
    try {
      isLoading(true);
      var realtime = await CommonApiProvider.realTimeData();
      if (realtime != null) {
        realtimeList.value = realtime;
      }
    } catch (e) {
      isLoading(false);
      // ignore: avoid_print
      print(e);
      rethrow;
    } finally {
      isLoading(false);
    }
  }

  loadMapStyle() async {
    String style = await rootBundle.loadString("assets/map_style.json");
    return style;
  }
}

这些代码运行良好,但似乎每次新数据到达时都会重新加载/刷新 Googlemap。如何仅在每次在数据库中更新新的纬度、经度时才更新标记的位置,而无需重新加载/刷新 Googlemap?

谢谢

【问题讨论】:

    标签: flutter dart flutter-getx


    【解决方案1】:

    您正在视图内初始化 allMarkers 列表,这就是为什么您需要手动刷新页面才能在地图上显示标记。

    MapViewController中初始化allMarkers

    List&lt;Marker&gt; allMarkers = &lt;Marker&gt;[].obs; // Inside Map View Controller

    然后,在 Google 地图小部件中替换标记属性

    Obx(() => GoogleMap(
                myLocationButtonEnabled: true,
                markers:Set<Marker>.of(controller.allMarkers), // <====== Update
                mapType: MapType.normal,
                initialCameraPosition: _initialCameraPosition,
                onMapCreated: (GoogleMapController gmcontroller) {
                  _controller.complete(gmcontroller);
                  gmcontroller.setMapStyle(controller.loadMapStyle());
                },
              ))
    

    getMarkers函数中

    getMarkers() {
        // Add this line. Create map view controller object
        final MapViewController _controller = Get.find(); // <======= Add
        //get markers from controller
        var realdata = mapcontroller.realtimeList;
    
        realdata.asMap().forEach((key, value) {
          var _marker = Marker(
              consumeTapEvents: true,
              markerId: MarkerId(key.toString()),
              position: LatLng(
                  double.parse(value.latitude), double.parse(value.longitude)),
              onTap: () {
                //do something here
              });
    
          _controller.allMarkers.add(_marker); // <===== Update
          _controller.update() // <=== Add, because you are using GetBuilder
        });
      }
    }
    

    【讨论】:

    • 感谢您的回复! Obx( () -&gt; GoogleMap (... 不会在每次出现新的标记数据时刷新/重新加载 Googlemap?
    • 如果我在控制器本身上移动getMarkers() 方法呢?
    • @WatsMyName 实际上,您不需要将 Google 地图小部件包装在 Obx 中,因为 Google 地图已经包装在 Get 构建器中,因此在此阶段使用 Obx 是不必要的,是的,只要构建器收到更改,它就会重新渲染是孩子
    • @WatsMyName 在控制器中移动 getMarkers 是一种推荐的方式。如果您有特定屏幕的控制器,那么您应该在控制器内编写与屏幕相关的所有功能
    • 没有办法防止重新渲染谷歌地图吗?更改仅发生在 Marker 的位置,因此重新渲染整个地图不是一个好主意。我认为每次重新加载地图时谷歌都会收取费用。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-11-11
    • 2015-10-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-10-24
    相关资源
    最近更新 更多