Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 2 years ago.
Improve this question
I trying to get current location by geolocator package by this code below
GoogleMapController mapController;
Position _currentPosition;
static final CameraPosition _kGooglePlex = CameraPosition(
target: LatLng(30.033333, 31.233334), // egypt
zoom: 5.4746,
);
and this is the button function which should go to the current location
onTap: () {
mapController.animateCamera(
CameraUpdate.newCameraPosition(
CameraPosition(
target: LatLng(
_currentPosition.latitude,
_currentPosition.longitude,
),
zoom: 18.0,
),
),
);
},
By looking at the ReadMe on Geolocator I would probable do it like this. I haven't tested it myself.
onTap: () async {
_currentPosition = await getCurrentPosition(desiredAccuracy: LocationAccuracy.high);
mapController.animateCamera(
CameraUpdate.newCameraPosition(
CameraPosition(
target: LatLng(
_currentPosition.latitude,
_currentPosition.longitude,
),
zoom: 18.0,
),
),
);
},
To me it looks like you did not assign any values to _currentPosition, just said it was of the type Position, therefore you get a null result
Related
I'm trying to build an app that loads a GoogleMap(), then after getting the user latitude and longitude moves to the that specific location.
I came up with this idea (code below), but it works only if I restart the app and if I don't it gives error: animateCamera was called on null.
How is it possible ? and how can i fix it ?
Thanks for answering :D
...
var mapController;
...
GoogleMap createMap() {
var initMap = GoogleMap(
onMapCreated: onMapCreated,
initialCameraPosition:
CameraPosition(target: LatLng(47.290542, 8.322641), zoom: 6.7),
);
return initMap;
}
...
void onMapCreated(controller) {
mapController = controller;
}
...
void moveCameraToUserLocation(searchedLocation2) async {
var location = await Geocode().getLatLng(searchedLocation2);
print("moving to: $location");
mapController.animateCamera(
CameraUpdate.newCameraPosition(
CameraPosition(
target: location,
zoom: 20,
),
),
);
...
build(context) {
return Scaffold(
body: createMap(),
...
Based on how you describe the problem, it looks like you are only calling the animate function as the map loads.
I suggest that you create a button that would handle and trigger the animate function and move the camera to the device location whenever tapped.
The following code snippet uses a ClipOval button and inside the OnTap() event you can call the method to get the device current location which will be triggered whenever the button is tapped.
ClipOval(
child: Material(
color: Colors.green[100], // button color
child: InkWell(
splashColor: Colors.green, // inkwell color
child: SizedBox(
width: 56,
height: 56,
child: Icon(Icons.my_location),
),
onTap: () {
// Add methods here that will be called whenever the button is tapped
mapController.animateCamera(CameraUpdate.newCameraPosition(CameraPosition(
target: LatLng(_currentPosition.latitude, _currentPosition.longitude),
zoom: 17.0)));
setState(() {
allMarkers.add(Marker(
markerId: MarkerId('Current Position'),
draggable: false,
position:
LatLng(_currentPosition.latitude, _currentPosition.longitude)));
});
},
),
),
)
Probably you are calling moveCameraToUserLocation function before map is created. From this part of the code I cannot se when you call thi function but my guess is that you call it from initstate. If you want to call this function immediately after widget is created move it to onMapCreated.
void onMapCreated(controller) {
mapController = controller;
moveCameraToUserLocation();
}
I have a map app that uses google_map_flutter package and displays a full screen themed map. My confusion is that when I build the app I receive an unhandled exception for setMapStyle, even though the map displays with the theme.
Unhandled Exception: NoSuchMethodError: The method 'setMapStyle' was
called on null. E/flutter (30877): Receiver: null E/flutter (30877):
Tried calling: setMapStyle("[\r\n {\r\n \"featureType\":
\"landscape\",\r\n \"elementType\": \"geometry\",\r\n.......
The theme is a json file that I load using the code in my initState below.
#override
void initState() {
super.initState();
// Show the campus Map
getSunData();
// _showCampusMap();
WidgetsBinding.instance.addObserver(this);
// Check location permission has been granted
PermissionHandler()
.checkPermissionStatus(PermissionGroup
.locationWhenInUse) //check permission returns a Future
.then(_updateStatus); // handling in callback to prevent blocking UI
rootBundle
.loadString('assets/themes/map/day/simple_bright.json')
.then((string) {
mapStyle = string;
});
getUserLocation();
}
My method for setting the style is here.
// method that is called on map creation and takes a MapController as a parameter
void _onMapCreated(GoogleMapController controller) async {
PermissionHandler()
.checkPermissionStatus(PermissionGroup
.locationWhenInUse) //check permission returns a Future
.then(_updateStatus); // handling in callback to prevent blocking UI
controller.setMapStyle(mapStyle);
}
Here is my GoogleMap code
_userLocation == null
? Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
CircularProgressIndicator(
backgroundColor: Theme.UniColour.primary[900],
),
SizedBox(height: 20.0),
Text("Retrieving your location..."),
],
),
)
: GoogleMap(
onMapCreated: _onMapCreated,
initialCameraPosition: // required parameter that sets the starting camera position. Camera position describes which part of the world you want the map to point at.
CameraPosition(
target: _userLocation,
zoom: _defaultZoom,
tilt: _tiltAngle), //LatLng(53.467125, -2.233966)
scrollGesturesEnabled: _scrollGesturesEnabled,
tiltGesturesEnabled: _tiltGesturesEnabled,
compassEnabled: _compassEnabled,
rotateGesturesEnabled: _rotateGesturesEnabled,
myLocationEnabled: _myLocationEnabled,
buildingsEnabled: _buildingsEnabled, // not added to db
indoorViewEnabled: _indoorViewEnabled, // not added to db
mapToolbarEnabled: _mapToolbarEnabled, // not added to db
myLocationButtonEnabled:
_myLocationButtonEnabled, // not added to db
mapType: _currentMapType,
zoomGesturesEnabled: _zoomGesturesEnabled,
cameraTargetBounds: CameraTargetBounds(
new LatLngBounds(
northeast: uniCampusNE,
southwest: uniCampusSW,
),
),
minMaxZoomPreference:
MinMaxZoomPreference(_minZoom, _maxZoom),
),
Any ideas why this exception is occurring, does it need fixing and how would I do that?
[EDIT]
void _updateStatus(PermissionStatus status) {
if (status != _status) {
// check status has changed
setState(() {
_status = status; // update
_onMapCreated(controller);
});
} else {
if (status != PermissionStatus.granted) {
//print("REQUESTING PERMISSION");
PermissionHandler().requestPermissions(
[PermissionGroup.locationWhenInUse]).then(_onStatusRequested);
}
}
}
The argument type 'Completer' can't be assigned
to the parameter type 'GoogleMapController'.
[/EDIT]
thanks
You need to initialize the Completer class, under your State class write the following:
Completer<GoogleMapController> _controller = Completer();
Then use the variable _controller when calling setMapStyle:
void _onMapCreated(GoogleMapController controller) async {
PermissionHandler()
.checkPermissionStatus(PermissionGroup
.locationWhenInUse) //check permission returns a Future
.then(_updateStatus); // handling in callback to prevent blocking UI
_controller.setMapStyle(mapStyle);
}
I have a google map on the very first page of my application after the splash screen.
When I run the app for the first time and a very new build, it crashes with this error on IOS: PlatformException(create_failed, can't create a view on a headless engine, null).
This is my google Map code and the crash happens only in IOS for the first time when the app is installed.
GoogleMap(
myLocationEnabled: false,
myLocationButtonEnabled: false,
zoomGesturesEnabled: true,
scrollGesturesEnabled: true,
rotateGesturesEnabled: false,
tiltGesturesEnabled: false,
onMapCreated: _onMapCreated,
initialCameraPosition: CameraPosition(
target: _location,
zoom: 12,
/* tilt: 50.0,
bearing: 45.0,*/
),
mapType: _currentMapType,
markers: Set<Marker>.of(markers.values),
onCameraMove: _onCameraMove,
onCameraIdle: _onCameraIdle,
)
I am following up on this issue on GitHub : https://github.com/flutter/flutter/issues/36310
but it is not having a proper solution.
Can anyone please help me with this?
Have you registered your API key properly and in the right spot?
This needs to be registered within the appDelegate class before the flutter engine kicks in. (Please note that this is a swift file)
import UIKit
import GoogleMaps
#UIApplicationMain
#objc class AppDelegate: FlutterAppDelegate {
override func application(
_ application: UIApplication,
didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
) -> Bool {
GMSServices.provideAPIKey("super_secret_api_key")
GeneratedPluginRegistrant.register(with: self);
return super.application(application, didFinishLaunchingWithOptions: launchOptions)
}
}
Ok so, I'm pretty new to Flutter language and I have to make an app with google maps that uses markers, and when you click in the marker's info window it has to open a new page with info about that marker, so I build the new page, placed the marker in the map and used onTap:(){} to move to the new page, but when I run the app and click the info window, nothing happens.
At first it showed me an error on the context line, I wrote a "BuildContext context;" and the error was solved but the Info windows still does nothing, I tried moving the "BuildContext context;" outside the marker but still the same, I tried to find other solutions in the internet but the only one I found was on this site and I didn't understand what the solution was, or didn't worked for me.
Marker servicioej= Marker(
markerId: MarkerId('marker1'),
position: LatLng(-32.3162695, -58.0949139),
infoWindow: InfoWindow(
title: 'Restaurante',
onTap: () {
BuildContext context;
Navigator.push(
context,
MaterialPageRoute(builder: (context) => ServicioStateful()),
);
}),
icon: BitmapDescriptor.defaultMarkerWithHue(BitmapDescriptor.hueBlue),
);
I just need that when I click on the marker it moves me to the other page, I've been with this problem since yesterday and I could use some help, sorry if there's some spelling mistakes I tried my best to make it understandable xD
Save a reference of your BuildContext which is provided by the build method in a variable and pass that context variable to the Navigator.
class MapScreen extends StatefulWidget{
...
}
class MapScreenState extends State<MapScreen>{
BuildContext _myContext;
#override
Widget build(BuildContext context) {
_myContext = context;
Marker servicioej= Marker(
markerId: MarkerId('marker1'),
position: LatLng(-32.3162695, -58.0949139),
infoWindow: InfoWindow(
title: 'Restaurante',
onTap: () {
Navigator.push(_myContext, MaterialPageRoute(builder: (context) => ServicioStateful()));
}),
icon: BitmapDescriptor.defaultMarkerWithHue(BitmapDescriptor.hueBlue),
);
return Scaffold(
...
);
}
}
I've recently started getting into flutter, but just as I was about to write a few widget tests, I noticed that I wasn't terribly sure how to mock out the Google Maps Flutter package.
Many examples I've seen include using the library "mockito" to mock out classes, but this assumes that the Google Maps widget will be injected into the widget to be tested. Unfortunately, with their given documentation and startup guide, this doesn't seem to be very possible:
class MapsDemo extends StatefulWidget {
#override
State createState() => MapsDemoState();
}
class MapsDemoState extends State<MapsDemo> {
GoogleMapController mapController;
#override
Widget build(BuildContext context) {
return Padding(
padding: EdgeInsets.all(15.0),
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: <Widget>[
Center(
child: SizedBox(
width: 300.0,
height: 200.0,
child: GoogleMap(
onMapCreated: _onMapCreated,
),
),
),
RaisedButton(
child: const Text('Go to London'),
onPressed: mapController == null ? null : () {
mapController.animateCamera(CameraUpdate.newCameraPosition(
const CameraPosition(
bearing: 270.0,
target: LatLng(51.5160895, -0.1294527),
tilt: 30.0,
zoom: 17.0,
),
));
},
),
],
),
);
}
void _onMapCreated(GoogleMapController controller) {
setState(() { mapController = controller; });
}
}
Note that the GoogleMaps widget cannot be passed in because onMapCreated is a required function, and that function relies private class method (give the parent widget access to GoogleMapsController). Many other examples of mockito mock functions that don't have this sort of callback function to set state.
There doesn't seem to be any other packages I've seen that can effectively mock out the GoogleMaps widget, so I don't really have any sort of example to follow. Ideally, what I was expecting was some sort of behavior like proxyquire or sinon in node.s (where you don't need to pass in the mocked libraries into function.constructors), but it looks like mockified classes need to be passed into the tested widgets.
Are there any other ideas on how to mock out this library for testing? Or should I just live with testing the actual functionality?
I managed to mock the GoogleMaps by mocking the channels it uses:
setUpAll(() async {
SystemChannels.platform_views.setMockMethodCallHandler((MethodCall call) {
switch (call.method) {
case 'create':
return Future<int>.sync(() => 1);
default:
return Future<void>.sync(() {});
}
});
MethodChannel('plugins.flutter.io/google_maps_0', StandardMethodCodec())
.setMockMethodCallHandler((MethodCall methodCall) async {
return null;
});
}
I got inspiration from this webview plugin test (which is a PlatformView like the GoogleMaps widget), as well as this GoogleMaps plugin test