I am using google maps flutter plugin for my App. I want the initial camera position target (the LatLng) to be exactly equal to the current device's latitude and longitude so that the camera on startup shows where the user currently is. However, I am running into issues trying to do this. I have tried using the Location and Geolocator packages but there is no clear cut example on how to do what I want to achieve.
When I try to use currentLocation.latitude
and currentLocation.longitude
for the Location package as the values for the Latlng in the camera target I am running into the below error.
"only static members can be accessed by initializers"
Frankly I don't know what that means in this context. I have read some examples but none clearly implements what I really want to achieve
import 'package:flutter/cupertino.dart';
import 'dart:async';
import 'package:flutter/material.dart';
import 'package:google_maps_flutter/google_maps_flutter.dart';
import 'package:location/location.dart';
class Map extends StatefulWidget {
@override
State<Map> createState() => MapState();
}
class MapState extends State<Map> {
Completer<GoogleMapController> _controller = Completer();
var currentLocation = LocationData;
var location = new Location();
Future _getLocation() async {
try {
location.onLocationChanged().listen((LocationData currentLocation) {
print('Latitude:${currentLocation.latitude}');
print('Longitude:${currentLocation.longitude}');
return LatLng(currentLocation.latitude, currentLocation.longitude);
});
} catch (e) {
print('ERROR:$e');
currentLocation = null;
}
}
static final CameraPosition _currentPosition = CameraPosition(
target: LatLng(currentLocation.latitude , currentLocation.longitude),
zoom: 14.4746,
);
@override
void initState() {
_getLocation();
super.initState();
}
@override
Widget build(BuildContext context) {
return new Scaffold(
body: GoogleMap(
mapType: MapType.normal,
initialCameraPosition: _currentPosition,
zoomGesturesEnabled: true,
myLocationButtonEnabled: true,
rotateGesturesEnabled: true,
tiltGesturesEnabled: true,
onMapCreated: (GoogleMapController controller) {
_controller.complete(controller);
},
),
);
}
}
That is my code snippet producing the error on the _currentPosition final which represents Camera position am equating it to current device's latitude and longitude using locator package but Flutter is complaining. I don't know how to do it correctly. I want the latlng target to be the latlng of the device
The issue concerning the error when displaying the map widget while getting the user current location is that, getting the user's actual current location is an asynchronous operation and thus the during that whole process initial position will be null thus we make a conditional that runs as we wait for the async operation to complete then display the map when then the value will be non-null. I have refactored the code and used the geolocator package instead
import 'package:flutter/cupertino.dart';
import 'dart:async';
import 'package:flutter/material.dart';
import 'package:geolocator/geolocator.dart';
import 'package:google_maps_flutter/google_maps_flutter.dart';
class Map extends StatefulWidget {
@override
_MapState createState() => _MapState();
}
class _MapState extends State<Map> {
Completer<GoogleMapController> controller1;
//static LatLng _center = LatLng(-15.4630239974464, 28.363397732282127);
static LatLng _initialPosition;
final Set<Marker> _markers = {};
static LatLng _lastMapPosition = _initialPosition;
@override
void initState() {
super.initState();
_getUserLocation();
}
void _getUserLocation() async {
Position position = await Geolocator().getCurrentPosition(desiredAccuracy: LocationAccuracy.high);
List<Placemark> placemark = await Geolocator().placemarkFromCoordinates(position.latitude, position.longitude);
setState(() {
_initialPosition = LatLng(position.latitude, position.longitude);
print('${placemark[0].name}');
});
}
_onMapCreated(GoogleMapController controller) {
setState(() {
controller1.complete(controller);
});
}
MapType _currentMapType = MapType.normal;
void _onMapTypeButtonPressed() {
setState(() {
_currentMapType = _currentMapType == MapType.normal
? MapType.satellite
: MapType.normal;
});
}
_onCameraMove(CameraPosition position) {
_lastMapPosition = position.target;
}
_onAddMarkerButtonPressed() {
setState(() {
_markers.add(
Marker(
markerId: MarkerId(_lastMapPosition.toString()),
position: _lastMapPosition,
infoWindow: InfoWindow(
title: "Pizza Parlour",
snippet: "This is a snippet",
onTap: (){
}
),
onTap: (){
},
icon: BitmapDescriptor.defaultMarker));
});
}
Widget mapButton(Function function, Icon icon, Color color) {
return RawMaterialButton(
onPressed: function,
child: icon,
shape: new CircleBorder(),
elevation: 2.0,
fillColor: color,
padding: const EdgeInsets.all(7.0),
);
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: _initialPosition == null ? Container(child: Center(child:Text('loading map..', style: TextStyle(fontFamily: 'Avenir-Medium', color: Colors.grey[400]),),),) : Container(
child: Stack(children: <Widget>[
GoogleMap(
markers: _markers,
mapType: _currentMapType,
initialCameraPosition: CameraPosition(
target: _initialPosition,
zoom: 14.4746,
),
onMapCreated: _onMapCreated,
zoomGesturesEnabled: true,
onCameraMove: _onCameraMove,
myLocationEnabled: true,
compassEnabled: true,
myLocationButtonEnabled: false,
),
Align(
alignment: Alignment.topRight,
child: Container(
margin: EdgeInsets.fromLTRB(0.0, 50.0, 0.0, 0.0),
child: Column(
children: <Widget>[
mapButton(_onAddMarkerButtonPressed,
Icon(
Icons.add_location
), Colors.blue),
mapButton(
_onMapTypeButtonPressed,
Icon(
IconData(0xf473,
fontFamily: CupertinoIcons.iconFont,
fontPackage: CupertinoIcons.iconFontPackage),
),
Colors.green),
],
)),
)
]),
),
);
}
}
GeoLocator API has been changed with latest upgraded Geolocator is no longer used. Instead GeolocatorPlatform is new keyword to access current postion as per latest updates
LatLng currentPostion;
void _getUserLocation() async {
var position = await GeolocatorPlatform.instance
.getCurrentPosition(desiredAccuracy: LocationAccuracy.high);
setState(() {
currentPostion = LatLng(position.latitude, position.longitude);
});
}
Use currentPostion in your googlemap. (define Latlag currentPosition);
GoogleMap(
// onMapCreated: _onMapCreated,
initialCameraPosition: CameraPosition(
target: currentPostion,
zoom: 10,
),
),
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With