I'm a novice in Flutter, and I encountered an issue with google maps plugin. I watched a couple of tutorials in order to get the current position of the camera and Most of them was using GoogleMapController.cameraPosition.target. I think they deleted this method from the controller(Since it is still on the development stage). Is there any other way of getting the current position of the camera?
If you are using the google_maps_flutter package:
The GoogleMap widget have the onCameraMove function that returns the CameraPosition while dragging the map or moving the camera.
To do this, you'll need to create a callback function called _getCameraPosition(CameraPosition cameraPosition which will be invoked when onCameraMove is called. For example:
void _getCameraPosition(CameraPosition cameraPosition) {
// You can do whatever you want with cameraPosition here
log("cameraPosition: " + cameraPosition.target.toString());
}
Then, you'll need to put the _getCameraPosition function to the onCameraMove field on GoogleMap widget, like this:
GoogleMap(
onCameraMove: _getCameraPosition, // pass it here
onMapCreated: _onMapCreated,
initialCameraPosition: CameraPosition(
target: LatLng(-33.86882, 151.209296),
zoom: 12,
),
),
As a result, you will get a LatLng value in the debug console. For example:
cameraPosition: LatLng(-33.8940124943736, 151.2027569487691)
Related
I am using Stream Builder that sends api request after some seconds and fetch coordinates (lat, lng).
I want to update the map location (camera position & marker) on newly fetch coordinates.
But Camera position is updating and not focusing on new coordinates.
My google map widget is inside of stream builder and in which we are passing data through snapshot
e.g latlng = LatLng(snapshot.data['lat'],snapshot.data['lng']) to markers: SetMarker( markers, markerID, latlng, ), & initialCameraPosition: CameraPosition( target: latlng, zoom: 9.0, )
The GoogleMaps widget on Flutter does have the attribute initialCameraPosition but as the name says this is just an initial value, if you want to update the map once this has loaded i'd recommend the use of the callback onMapCreated, where you can use the controller to animate to a certain position.
Doing so would look something like this:
onMapCreated: (GoogleMapController controller) {
controller.animateCamera(
CameraUpdate.newCameraPosition(CameraPosition(
target: LatLng(snapshot.data['lat'],
snapshot.data['lng']),
zoom: 12)));
setState((){});
}
Hope this helps! ;)
I have created a Flutter app that uses Google maps. It gets the user's location and centers on that point. As the user walks around the camera will follow it but ONLY if the user hasn't manually moved the camera themselves (_userMovedMap = 0). Once they have moved the map it will no longer follow them...
#override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
),
body: Listener(
onPointerMove: (e) {
_userMovedMap = true;
},
child: GoogleMap(
onMapCreated: _onMapCreated,
myLocationButtonEnabled: true,
myLocationEnabled: true,
initialCameraPosition: CameraPosition(
target: _center,
zoom: _zoom,
),
),
),
),
);
}
Here is the location update listener, which also tells the camera to move if "_userMovedMap" is false :
Geolocator.getPositionStream().listen((Position _newLocation) {
//update position with new location data
setState(() {
_center = LatLng(_newLocation.latitude, _newLocation.longitude);
//Move camera to center of location if !_userMovedMap
if (!_userMovedMap) moveCamera();
});
});
...this all works great.
But I want to listen for the user clicking the generic "my location" button (standard google button shown in the top-right of the map). The button can do what its supposed to (animates the camera to current location), but I aso want it to reset "_userMovedMap" to false again.
From what I've seen it's something to do with "setOnMyLocationButtonClickListener", but Google Maps Flutter widget doesn't recognise it.
Can anyone help?
Thanks
I couldn't find an answer - I don't think it is currently possible. It seems to be a "severe" request in a later googlemaps plugin update, but nothing is on the roadmap.
Therefore I made my own location button.
https://pub.dev/packages/flutter_animarker
Wow, this is annoying. So Animarker is a Widget parent for my Google map. The map is busy with Markers. When the user needs to find a particular Marker from the drawer, they tap the item & it triggers a Ripple effect in the corresponding Marker.
The problem is it never stops rippling. It'll even attempt to animate several Markers if the user keeps on tapping.
It was love at first animation but I'm climbing the walls now!
Animarker(
isActiveTrip: rippleAnimationActive,
rippleRadius: 0.5, //[0,1.0] range, how big is the circle
rippleColor: Colors.teal, // Color of fade ripple circle
rippleDuration: Duration(milliseconds: 2500), //Pulse ripple duration
markers: animatedMarkerSet,
mapId: _mapController.future.then<int>((value) => value.mapId),
child: GoogleMap(
key: Key("myGoogleMap"),
mapType: MapType.hybrid,
initialCameraPosition: _edinburghCamera,
markers: _markers,
myLocationEnabled: true,
onMapCreated: (GoogleMapController controller) {
_mapController.complete(controller);
},
),
),
I trigger the animation in a Drawer item onTap():
onTap: () {
animatedMarkerSet = {
RippleMarker(
markerId: MarkerId(presentLocation.name),
position: presentLocation.latLng,
ripple: true) };
setState(() {
presentLocation = _location;
animatedMarkerSet;
rippleAnimationActive = true;
});
//setState(() => _markers.add(marker));
Navigator.of(context).pop();
},
You can see I've created a brand new Marker to animate, and added it to the animatedMarkerSet. This works fine.
When the user taps a Marker, any Marker, details about the location slide up. And I try to deactivate ANY Marker which is rippling. However no matter what I try it doesn't stop:
setState(() {
rippleAnimationActive = false;
animatedMarkerSet.clear(); // nuke from orbit
}
I've also tried changing the animatedMarkerSet to a Map, and attempting to deactivate the ripple using this:
void newLocationUpdate(LocationDetails oldLocation) {
var marker = RippleMarker(
markerId: MarkerId(oldLocation.name),
position: oldLocation.latLng,
ripple: false,
);
setState(() => animatedMarkerMap[MarkerId(oldLocation.name)] = marker);
}
But that doesn't work either.
I really really just need to switch the animation on and off. I don't see why Animarker's so resistant to setState(), telling it to stop.
In fact, the best thing might be to just have it run for 5 seconds then switch off, in all circumstances, but I fail to see how to do that either. Grrrr!
OK well I figured it out. AniMarker which takes the Set of animated Markers, is final. So once you hand it the set of say RippleMarkers, it'll animate them, but you can't then turn it off via a SetState() call.
I tried editing the AniMarker class, to make it not final, so you could mutate it's dataset, but I think because it's built on GoogleMap's Marker class, and they're final, it just will not work.
So AniMarker presently has limited utility.
My work around was just to mutate GoogleMaps marker: option, so I could highlight a Marker by changing it's color. It's also possible to change the circles: GoogleMap option to dyanically highlight a Marker according to user interaction.
I'm pretty new in Flutter. It is amazing. I'm working on small app usign google maps. I have 6 points (Markers) and need to recognize which one was selected.
I've added ontap event into every marker with i-index (i = 0..5). When I tap/click on marker I always get 6. It should be 0..5 based on marker.
Thanx a lot, Gabriel
i=0;
marker.clear();
for (myPoint mar in globals.historia.items) {
print(i.toString());
marker.add(Marker(
markerId: MarkerId(i.toString()),
position: mar.pos,
draggable: false,
consumeTapEvents: true,
onTap: () {
print("Marker_id-${i.toString()}");
},
));
i++;
}
GoogleMap(
onMapCreated: _onMapCreated,
initialCameraPosition: CameraPosition(
target: myposition,
zoom: 17.0,
),
polylines: road,
markers: Set.of(marker),
)
When onTap() is triggered it calls i with its last value that's == 6, that's why every time you tap on a marker, the print method prints 6.
i is a global variable, that has its own address, so the print method will search for the value on that address every time onTap is called.
I propose this solution - replace youtr print method inside onTap with this : print("Marker_id-${globals.historia.items.indexOf(mar)}")
mar is a local variable inside the for in loop, and its value has never changed, so he will point on the same value, onTap will behave as you want.
I am trying to create a sample app like Uber with google_maps_flutter: ^0.5.10 .. In Uber app when you select a pickup/drop location, and you do double tap (to zoom in) or zoom in/zoom out scaling the screen it always happens respective to the center of screen. Whereas when I add the google maps in flutter and if I do double tap lets say on right bottom of screen, google maps zoom and takes the view to the area where it was tapped. Similarly it happens with the scaling (pinching screen). The area I scale the camera view goes to that particular location. But I want double tap or scaling to stay centered to my selected location (like in Uber).
I did achieve it using cameraMove and cameraStop callbacks. In that I determine if camera was moved due to a zoom, I get the last zoom factor and move camera back to my selected location with the new zoom factor. It works but does not looks good if I double tap on left corner the camera goes back to original position. Similarly I did for the scaling zoom as well to zoom in/zoom out the camera moves back to original location I selected.
Then I tried GestureDetector on top of the GoogleMaps. Inside that I handled the onDoubleTap. That looks neat as I just change the zoom factor on double tap and keep location same. But I am not able to achieve scaling zoom in/out using onScaleUpdate (etc) functions on GestureDetector.
Is there any better way in Google maps flutter plugin to do all this?
use onCameraMove this will listen to the change of the cameraPosition.
for instance if you zoom in using double tap or zoom in/out using gestures,
GoogleMap(
zoomGesturesEnabled: true,
tiltGesturesEnabled: false,
onCameraMove:(CameraPosition cameraPosition){
print(cameraPosition.zoom);
},
onCameraMove take a void function and pass to it the CameraPosition argument, so you can use
"cameraPosition.zoom" to return the current zoom level; "cameraPosition.tilt" return the current tilt angle ...
use zoomGesturesEnabled: true
like that :
import 'dart:async';
import 'package:flutter/material.dart';
import 'package:google_maps_flutter/google_maps_flutter.dart';
class ZoomInOutMaps extends StatefulWidget {
#override
_ZoomInOutMapsState createState() => _ZoomInOutMapsState();
}
class _ZoomInOutMapsState extends State<ZoomInOutMaps> {
Completer<GoogleMapController> _controller = Completer();
static const LatLng _center = const LatLng(45.521563, -122.677433);
void _onMapCreated(GoogleMapController controller) {
_controller.complete(controller);
}
#override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: Text('Zoom in and Out of Google Maps'),
backgroundColor: Colors.red,
),
body: GoogleMap(
//enable zoom gestures
zoomGesturesEnabled: true,
onMapCreated: _onMapCreated,
initialCameraPosition: CameraPosition(
target: _center,
zoom: 11.0,
),
),
),
);
}
}
Use below for handling min and max zoom:
minMaxZoomPreference: MinMaxZoomPreference(13,17)