Flutter:如何使用 Getx Obx 更新谷歌地图中的标记位置?

Wat*_*ame 4 dart flutter flutter-getx

我有以下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);
    });
  }
}
Run Code Online (Sandbox Code Playgroud)

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

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;
  }
}
Run Code Online (Sandbox Code Playgroud)

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

谢谢

小智 6

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

初始化里面的allMarkersMapViewController

List<Marker> allMarkers = <Marker>[].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());
            },
          ))
Run Code Online (Sandbox Code Playgroud)

并在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
    });
  }
}
Run Code Online (Sandbox Code Playgroud)