自定义 Google 地图标记 Flutter
Custom Google Maps Marker Flutter
我在使用 flutter 的 GoogleMaps 项目中使用自定义标记时遇到问题。我在地图屏幕加载时收到此错误
发生异常。
LateError(LateInitializationError:字段 'myMarker' 尚未初始化。)
我试过不使用 late,它说 myMarker 必须初始化,所以我声明它为 late,然后在 initState 中初始化它。那没有用,所以我尝试使用可为空的 ?
并且也没有用。任何帮助,将不胜感激。
谢谢
import 'dart:async';
import 'dart:developer';
import 'dart:io';
import 'package:flutter/material.dart';
import 'package:geolocator/geolocator.dart';
import 'package:google_maps_flutter/google_maps_flutter.dart';
import 'package:permission_handler/permission_handler.dart';
import 'package:location/location.dart';
import 'dart:math' as math;
import './main.dart' as main;
import './variables.dart' as variables;
import './methods.dart' as methods;
import './mapvariables.dart' as mapVar;
import './marker_information.dart' as markerInfo;
class MapScreen extends StatefulWidget {
const MapScreen({Key? key}) : super(key: key);
@override
_MapScreenState createState() => _MapScreenState();
}
class _MapScreenState extends State<MapScreen> {
Completer<GoogleMapController> _controllerGoogleMap = Completer();
late GoogleMapController newGoogleMapController;
Position? currentPosition;
var geoLocator = Geolocator();
final double dcheck = 0.00014128694207108202;
var location = new Location();
late BitmapDescriptor myMarker;
@override
void initState() {
super.initState();
setMarker();
}
void setMarker() async {
myMarker = await BitmapDescriptor.fromAssetImage(
ImageConfiguration(), 'loginlogo.png');
}
checkpermission_location() async {
var locationStatus = await Permission.location.status;
print(locationStatus);
if (!locationStatus.isGranted) {
print("gr");
print(await Permission.location.value);
await Permission.location.request();
checkpermission_location();
}
if (!locationStatus.isDenied) {
print('de');
await Permission.location.request();
checkLocation();
}
}
void checkClue(var x, var y, markerInfo.ClueLocation marker) {
double distance = methods.distance(marker.lat, marker.long, x, y);
log("distance: $distance");
if ((distance < dcheck)) {
variables.dialogVis = true;
if ((variables.dialogVis) && (marker.compl == false)) {
mapVar.showAlertDialog(context, marker);
variables.dialogVis = false;
marker.compl = true;
}
}
}
void checkLocation() {
location.onLocationChanged.listen((LocationData currentLocation) {
var lat = currentLocation.latitude;
var long = currentLocation.longitude;
checkClue(lat, long, markerInfo.newHamCollege);
checkClue(lat, long, markerInfo.coeFen);
checkClue(lat, long, markerInfo.mathematicalBridge);
checkClue(lat, long, markerInfo.graveYard);
checkClue(lat, long, markerInfo.archeologicalMuseum);
checkClue(lat, long, markerInfo.addenbrokesHospital);
checkClue(lat, long, markerInfo.stMarysBellTower);
checkClue(lat, long, markerInfo.trinityStreet);
checkClue(lat, long, markerInfo.viewOfTheBridgeOfSighs);
});
}
//Initial camera position when maps first load
static const _initalCameraPosition = CameraPosition(
target: LatLng(52.2053, 0.1218),
zoom: 11.5,
);
Marker makeMarker(markerInfo.ClueLocation marker) {
return (Marker(
markerId: MarkerId(marker.title),
infoWindow: InfoWindow(title: marker.title),
icon: myMarker,
position: LatLng(marker.lat, marker.long),
onTap: () {
if (marker.compl) {
mapVar.showAlertDialog(context, marker);
}
}));
}
//Google map widget
@override
Widget build(BuildContext context) {
//Checks if mapAcess is true
if (variables.mapAccess) {
var currentlocation = location.getLocation();
return Scaffold(
body: GoogleMap(
onMapCreated: (GoogleMapController controller) {
controller.setMapStyle(mapVar.mapStyle);
checkpermission_location();
_controllerGoogleMap.complete(controller);
newGoogleMapController = controller;
},
mapType: MapType.normal,
myLocationButtonEnabled: true,
zoomControlsEnabled: true,
myLocationEnabled: true,
zoomGesturesEnabled: true,
markers: {
//Markers located in the variables.dart file
makeMarker(markerInfo.newHamCollege),
makeMarker(markerInfo.coeFen),
makeMarker(markerInfo.mathematicalBridge),
makeMarker(markerInfo.graveYard),
makeMarker(markerInfo.archeologicalMuseum),
//6.??? Waiting for update from Konstantin
makeMarker(markerInfo.addenbrokesHospital),
makeMarker(markerInfo.stMarysBellTower),
makeMarker(markerInfo.trinityStreet),
makeMarker(markerInfo.viewOfTheBridgeOfSighs),
},
initialCameraPosition: _initalCameraPosition,
),
);
}
//Refuses access if 10 Digit key is not provided
return Scaffold(
body: Center(
child: Text('You do not have access to the map, please login')));
}
}
你和我做的差不多;我的做法如下:
- 在您的状态 class 顶部将 BitmapDescriptor 设置为可为 null 的 属性,同时我创建一个 标记 集:
Set<Marker>? _markers = <Marker>{};
BitmapDescriptor? myMarker
我在 build 方法的开头创建了一个 async 方法 运行 (我在build 方法,因为我有时需要构建上下文),异步加载位图,如:
void setMarkerIcon() async {
myMarker = await BitmapDescriptor.fromAssetImage(
const ImageConfiguration(size: Size(50, 50)),'loginlogo.png');
}
然后在 build 方法中我只是调用它:
@override
Widget build(BuildContext context) {
// you can call it here
setMarkerIcons();
return Scaffold(
body: GoogleMap(
markers: _markers!,
onMapCreated: (GoogleMapController ctrl) {
// here after map is loaded, I generate the markers
generateMarkers();
}
)
);
奖金:
然后如上所示,在创建地图后,我可以继续使用基于位置列表的自定义标记,如下所示:
void generateMarkers() {
var localMarkers = <Marker>{};
for(var location in locationsList!) {
localMarkers.add(
Marker(
markerId: MarkerId(location.id!),
position: LatLng(location.lat!, location.lng!),
icon: myMarker
)
);
}
if (mounted) {
setState(() {
_markers = localMarkers;
});
}
}
我在使用 flutter 的 GoogleMaps 项目中使用自定义标记时遇到问题。我在地图屏幕加载时收到此错误
发生异常。 LateError(LateInitializationError:字段 'myMarker' 尚未初始化。)
我试过不使用 late,它说 myMarker 必须初始化,所以我声明它为 late,然后在 initState 中初始化它。那没有用,所以我尝试使用可为空的 ?
并且也没有用。任何帮助,将不胜感激。
谢谢
import 'dart:async';
import 'dart:developer';
import 'dart:io';
import 'package:flutter/material.dart';
import 'package:geolocator/geolocator.dart';
import 'package:google_maps_flutter/google_maps_flutter.dart';
import 'package:permission_handler/permission_handler.dart';
import 'package:location/location.dart';
import 'dart:math' as math;
import './main.dart' as main;
import './variables.dart' as variables;
import './methods.dart' as methods;
import './mapvariables.dart' as mapVar;
import './marker_information.dart' as markerInfo;
class MapScreen extends StatefulWidget {
const MapScreen({Key? key}) : super(key: key);
@override
_MapScreenState createState() => _MapScreenState();
}
class _MapScreenState extends State<MapScreen> {
Completer<GoogleMapController> _controllerGoogleMap = Completer();
late GoogleMapController newGoogleMapController;
Position? currentPosition;
var geoLocator = Geolocator();
final double dcheck = 0.00014128694207108202;
var location = new Location();
late BitmapDescriptor myMarker;
@override
void initState() {
super.initState();
setMarker();
}
void setMarker() async {
myMarker = await BitmapDescriptor.fromAssetImage(
ImageConfiguration(), 'loginlogo.png');
}
checkpermission_location() async {
var locationStatus = await Permission.location.status;
print(locationStatus);
if (!locationStatus.isGranted) {
print("gr");
print(await Permission.location.value);
await Permission.location.request();
checkpermission_location();
}
if (!locationStatus.isDenied) {
print('de');
await Permission.location.request();
checkLocation();
}
}
void checkClue(var x, var y, markerInfo.ClueLocation marker) {
double distance = methods.distance(marker.lat, marker.long, x, y);
log("distance: $distance");
if ((distance < dcheck)) {
variables.dialogVis = true;
if ((variables.dialogVis) && (marker.compl == false)) {
mapVar.showAlertDialog(context, marker);
variables.dialogVis = false;
marker.compl = true;
}
}
}
void checkLocation() {
location.onLocationChanged.listen((LocationData currentLocation) {
var lat = currentLocation.latitude;
var long = currentLocation.longitude;
checkClue(lat, long, markerInfo.newHamCollege);
checkClue(lat, long, markerInfo.coeFen);
checkClue(lat, long, markerInfo.mathematicalBridge);
checkClue(lat, long, markerInfo.graveYard);
checkClue(lat, long, markerInfo.archeologicalMuseum);
checkClue(lat, long, markerInfo.addenbrokesHospital);
checkClue(lat, long, markerInfo.stMarysBellTower);
checkClue(lat, long, markerInfo.trinityStreet);
checkClue(lat, long, markerInfo.viewOfTheBridgeOfSighs);
});
}
//Initial camera position when maps first load
static const _initalCameraPosition = CameraPosition(
target: LatLng(52.2053, 0.1218),
zoom: 11.5,
);
Marker makeMarker(markerInfo.ClueLocation marker) {
return (Marker(
markerId: MarkerId(marker.title),
infoWindow: InfoWindow(title: marker.title),
icon: myMarker,
position: LatLng(marker.lat, marker.long),
onTap: () {
if (marker.compl) {
mapVar.showAlertDialog(context, marker);
}
}));
}
//Google map widget
@override
Widget build(BuildContext context) {
//Checks if mapAcess is true
if (variables.mapAccess) {
var currentlocation = location.getLocation();
return Scaffold(
body: GoogleMap(
onMapCreated: (GoogleMapController controller) {
controller.setMapStyle(mapVar.mapStyle);
checkpermission_location();
_controllerGoogleMap.complete(controller);
newGoogleMapController = controller;
},
mapType: MapType.normal,
myLocationButtonEnabled: true,
zoomControlsEnabled: true,
myLocationEnabled: true,
zoomGesturesEnabled: true,
markers: {
//Markers located in the variables.dart file
makeMarker(markerInfo.newHamCollege),
makeMarker(markerInfo.coeFen),
makeMarker(markerInfo.mathematicalBridge),
makeMarker(markerInfo.graveYard),
makeMarker(markerInfo.archeologicalMuseum),
//6.??? Waiting for update from Konstantin
makeMarker(markerInfo.addenbrokesHospital),
makeMarker(markerInfo.stMarysBellTower),
makeMarker(markerInfo.trinityStreet),
makeMarker(markerInfo.viewOfTheBridgeOfSighs),
},
initialCameraPosition: _initalCameraPosition,
),
);
}
//Refuses access if 10 Digit key is not provided
return Scaffold(
body: Center(
child: Text('You do not have access to the map, please login')));
}
}
你和我做的差不多;我的做法如下:
- 在您的状态 class 顶部将 BitmapDescriptor 设置为可为 null 的 属性,同时我创建一个 标记 集:
Set<Marker>? _markers = <Marker>{};
BitmapDescriptor? myMarker
我在 build 方法的开头创建了一个 async 方法 运行 (我在build 方法,因为我有时需要构建上下文),异步加载位图,如:
void setMarkerIcon() async {
myMarker = await BitmapDescriptor.fromAssetImage(
const ImageConfiguration(size: Size(50, 50)),'loginlogo.png');
}
然后在 build 方法中我只是调用它:
@override
Widget build(BuildContext context) {
// you can call it here
setMarkerIcons();
return Scaffold(
body: GoogleMap(
markers: _markers!,
onMapCreated: (GoogleMapController ctrl) {
// here after map is loaded, I generate the markers
generateMarkers();
}
)
);
奖金:
然后如上所示,在创建地图后,我可以继续使用基于位置列表的自定义标记,如下所示:
void generateMarkers() {
var localMarkers = <Marker>{};
for(var location in locationsList!) {
localMarkers.add(
Marker(
markerId: MarkerId(location.id!),
position: LatLng(location.lat!, location.lng!),
icon: myMarker
)
);
}
if (mounted) {
setState(() {
_markers = localMarkers;
});
}
}