Flutter:如何使用 Getx Obx 更新标记在谷歌地图中的位置?
Posted
技术标签:
【中文标题】Flutter:如何使用 Getx Obx 更新标记在谷歌地图中的位置?【英文标题】:Flutter: How do I update markers' position in google map using 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?
谢谢
【问题讨论】:
【参考方案1】:您正在视图内初始化 allMarkers 列表,这就是为什么您需要手动刷新页面才能在地图上显示标记。
在MapViewController
中初始化allMarkers
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());
,
))
在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( () -> GoogleMap (...
不会在每次出现新的标记数据时刷新/重新加载 Googlemap?
如果我在控制器本身上移动getMarkers()
方法呢?
@WatsMyName 实际上,您不需要将 Google 地图小部件包装在 Obx 中,因为 Google 地图已经包装在 Get 构建器中,因此在此阶段使用 Obx 是不必要的,是的,只要构建器收到更改,它就会重新渲染是孩子
@WatsMyName 在控制器中移动 getMarkers 是一种推荐的方式。如果您有特定屏幕的控制器,那么您应该在控制器内编写与屏幕相关的所有功能
没有办法防止重新渲染谷歌地图吗?更改仅发生在 Marker 的位置,因此重新渲染整个地图不是一个好主意。我认为每次重新加载地图时谷歌都会收取费用。以上是关于Flutter:如何使用 Getx Obx 更新标记在谷歌地图中的位置?的主要内容,如果未能解决你的问题,请参考以下文章
我正在使用 Getx 进行状态管理,当我将数据添加到服务器时,它不会在列表视图中出现更新的数据,直到热重启而列表视图位于 Obx 中
使用 Obx,得到这个错误:[Get] 检测到 GetX 使用不当
使用 GetX 可观察对象时,哪些 UI 小部件需要包装在 Obx 中?
Flutter之GetX入门指南 ObxWidget原理剖析