A flutter plugin for displaying google maps on iOS and Android
Please note: API changes are likely as we continue to develop this plugin.
Google Maps Android API
Google Maps SDK for iOS
Credentials
, choose Create Credential
. The way you register your API key on iOS vs Android is different. Make sure to read the next sections carefully.
ios/Runner/Info.plist
. Example: <key>NSLocationWhenInUseUsageDescription</key>
<string>Using location to display on a map</string>
import 'package:map_view/map_view.dart';
void main() {
MapView.setApiKey("<your_api_key>");
runApp(new MyApp());
}
Note: If your iOS and Android API key are different, be sure to use your iOS API key here.
//Create an instance variable for the mapView
var _mapView = new MapView();
//Add a method to call to show the map.
void showMap() {
_mapView.show(new MapOptions(showUserLocation: true));
}
```
ClientParametersRequest failed, 7 attempts remaining (0 vs 12). Error Domain=com.google.HTTPStatus Code=400 "(null)" UserInfo={data=<>}
Your Bundle ID does not match what is registered in the Google API Console. When you create an restricted API key in the Google API console it asks you to specify your iOS bundle ID. Make sure that your iOS Bundle Identifier matches the one you registered in the console.
Using the wrong key. If you made a separate key for iOS and Android, make sure you are using the iOS key in the MapView.setApiKey() call.
You will be making multiple edits to your AndroidManifest.xml
file. In your Flutter project, you can
find this file location under android/app/src/main
In your AndroidManifest.xml
, add the following uses-permission above the <application> tag.
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
In your AndroidManifest.xml, add the following lines inside of the application
tag. Be sure to replace your_api_key
with the one you generated.
<meta-data android:name="com.google.android.maps.v2.API_KEY" android:value="your_api_key"/>
<meta-data android:name="com.google.android.gms.version" android:value="@integer/google_play_services_version"/>
Add the MapActivity to your AndroidManifest.xml
<activity android:name="com.apptreesoftware.mapview.MapActivity" android:theme="@style/Theme.AppCompat.Light.DarkActionBar"/>
In your android/build.gradle
file. Under buildScript
dependencies
add:
classpath 'org.jetbrains.kotlin:kotlin-gradle-plugin:1.1.2-4'
Run your application on an Android device or simulator. Confirm that when you display the map you see map detail. If you only see a beige screen it's possible that your API key is incorrect.
This plugin does not currently support displaying a Google Map within the Flutter widget hierarchy. A common workaround for this is to show a static image using the Google Static Maps API. Included in this Plugin is the StaticMapProvider class which will allow you to easily generate a static map. The Static Maps API also requires an API Key and you must enable the API within the Google API Console.
Google Static Maps API
var provider = new StaticMapProvider('your_api_key');
var uri = staticMapProvider.getImageUriFromMap(mapView,
width: 900, height: 400);
You can refer to the example project if you run into any issues with these steps.
![]() |
![]() |
mapView.show(
new MapOptions(
mapViewType: MapViewType.normal,
showUserLocation: true,
initialCameraPosition: new CameraPosition(
new Location(45.5235258, -122.6732493), 14.0),
title: "Recently Visited"),
toolbarActions: [new ToolbarAction("Close", 1)]);
mapView.onMapReady.listen((_) {
print("Map ready");
});
mapView.setMarkers(<Marker>[
new Marker("1", "Work", 45.523970, -122.663081, color: Colors.blue),
new Marker("2", "Nossa Familia Coffee", 45.528788, -122.684633),
]);
mapView.addMarker(new Marker("3", "10 Barrel", 45.5259467, -122.687747,
color: Colors.purple));
mapView.zoomToFit(padding: 100);
mapView.onLocationUpdated
.listen((location) => print("Location updated $location"));
mapView.onTouchAnnotation.listen((marker) => print("marker tapped"));
mapView.onMapTapped
.listen((location) => print("Touched location $location"));
mapView.onCameraChanged.listen((cameraPosition) =>
this.setState(() => this.cameraPosition = cameraPosition));
mapView.onToolbarAction.listen((id) {
if (id == 1) {
_handleDismiss();
}
});
double zoomLevel = await mapView.zoomLevel;
Location centerLocation = await mapView.centerLocation;
List<Marker> visibleAnnotations = await mapView.visibleAnnotations;
package:map_view/map_view.dart
example/lib/main.dart
import 'dart:async';
import 'package:flutter/material.dart';
import 'package:map_view/map_view.dart';
///This API Key will be used for both the interactive maps as well as the static maps.
///Make sure that you have enabled the following APIs in the Google API Console (https://console.developers.google.com/apis)
/// - Static Maps API
/// - Android Maps API
/// - iOS Maps API
var API_KEY = "<your_api_key>";
void main() {
MapView.setApiKey(API_KEY);
runApp(new MyApp());
}
class MyApp extends StatefulWidget {
@override
_MyAppState createState() => new _MyAppState();
}
class _MyAppState extends State<MyApp> {
MapView mapView = new MapView();
CameraPosition cameraPosition;
var compositeSubscription = new CompositeSubscription();
var staticMapProvider = new StaticMapProvider(API_KEY);
Uri staticMapUri;
@override
initState() {
super.initState();
cameraPosition = new CameraPosition(Locations.portland, 12.0);
staticMapUri = staticMapProvider.getStaticUri(Locations.portland, 12,
width: 900, height: 400);
}
@override
Widget build(BuildContext context) {
return new MaterialApp(
home: new Scaffold(
appBar: new AppBar(
title: new Text('Map View Example'),
),
body: new Column(
mainAxisAlignment: MainAxisAlignment.start,
children: <Widget>[
new Container(
height: 250.0,
child: new Stack(
children: <Widget>[
new Center(
child: new Container(
child: new Text(
"You are supposed to see a map here.\n\nAPI Key is not valid.\n\n"
"To view maps in the example application set the "
"API_KEY variable in example/lib/main.dart. "
"\n\nIf you have set an API Key but you still see this text "
"make sure you have enabled all of the correct APIs "
"in the Google API Console. See README for more detail.",
textAlign: TextAlign.center,
),
padding: const EdgeInsets.all(20.0),
)),
new InkWell(
child: new Center(
child: new Image.network(staticMapUri.toString()),
),
onTap: showMap,
)
],
),
),
new Container(
padding: new EdgeInsets.only(top: 10.0),
child: new Text(
"Tap the map to interact",
style: new TextStyle(fontWeight: FontWeight.bold),
),
),
new Container(
padding: new EdgeInsets.only(top: 25.0),
child: new Text(
"Camera Position: \n\nLat: ${cameraPosition.center.latitude}\n\nLng:${cameraPosition.center.longitude}\n\nZoom: ${cameraPosition.zoom}"),
),
],
)),
);
}
showMap() {
mapView.show(
new MapOptions(
mapViewType: MapViewType.normal,
showUserLocation: true,
initialCameraPosition: new CameraPosition(
new Location(45.5235258, -122.6732493), 14.0),
title: "Recently Visited"),
toolbarActions: [new ToolbarAction("Close", 1)]);
var sub = mapView.onMapReady.listen((_) {
mapView.setMarkers(<Marker>[
new Marker("1", "Work", 45.523970, -122.663081, color: Colors.blue),
new Marker("2", "Nossa Familia Coffee", 45.528788, -122.684633),
]);
mapView.addMarker(new Marker("3", "10 Barrel", 45.5259467, -122.687747,
color: Colors.purple));
mapView.zoomToFit(padding: 100);
});
compositeSubscription.add(sub);
sub = mapView.onLocationUpdated
.listen((location) => print("Location updated $location"));
compositeSubscription.add(sub);
sub = mapView.onTouchAnnotation
.listen((annotation) => print("annotation tapped"));
compositeSubscription.add(sub);
sub = mapView.onMapTapped
.listen((location) => print("Touched location $location"));
compositeSubscription.add(sub);
sub = mapView.onCameraChanged.listen((cameraPosition) =>
this.setState(() => this.cameraPosition = cameraPosition));
compositeSubscription.add(sub);
sub = mapView.onToolbarAction.listen((id) {
if (id == 1) {
_handleDismiss();
}
});
compositeSubscription.add(sub);
sub = mapView.onInfoWindowTapped.listen((marker) {
print("Info Window Tapped for ${marker.title}");
});
compositeSubscription.add(sub);
}
_handleDismiss() async {
double zoomLevel = await mapView.zoomLevel;
Location centerLocation = await mapView.centerLocation;
List<Marker> visibleAnnotations = await mapView.visibleAnnotations;
print("Zoom Level: $zoomLevel");
print("Center: $centerLocation");
print("Visible Annotation Count: ${visibleAnnotations.length}");
var uri = await staticMapProvider.getImageUriFromMap(mapView,
width: 900, height: 400);
setState(() => staticMapUri = uri);
mapView.dismiss();
compositeSubscription.cancel();
}
}
class CompositeSubscription {
Set<StreamSubscription> _subscriptions = new Set();
void cancel() {
for (var n in this._subscriptions) {
n.cancel();
}
this._subscriptions = new Set();
}
void add(StreamSubscription subscription) {
this._subscriptions.add(subscription);
}
void addAll(Iterable<StreamSubscription> subs) {
_subscriptions.addAll(subs);
}
bool remove(StreamSubscription subscription) {
return this._subscriptions.remove(subscription);
}
bool contains(StreamSubscription subscription) {
return this._subscriptions.contains(subscription);
}
List<StreamSubscription> toList() {
return this._subscriptions.toList();
}
}
Add this to your package's pubspec.yaml file:
dependencies:
map_view: ^0.0.6
You can install packages from the command line:
with pub:
$ pub get
with Flutter:
$ flutter packages get
Alternatively, your editor might support pub get
or flutter packages get
.
Check the docs for your editor to learn more.
Now in your Dart code, you can use:
import 'package:map_view/map_view.dart';
Version | Uploaded | Documentation | Archive |
---|---|---|---|
0.0.14 | Jul 20, 2018 |
|
|
0.0.13 | Jul 18, 2018 |
|
|
0.0.12 | Apr 17, 2018 |
|
|
0.0.11 | Apr 16, 2018 |
|
|
0.0.10 | Dec 30, 2017 |
|
|
0.0.9 | Dec 30, 2017 |
|
|
0.0.8 | Dec 29, 2017 |
|
|
0.0.7 | Dec 29, 2017 |
|
|
0.0.6 | Dec 27, 2017 |
|
|
0.0.5 | Nov 14, 2017 |
|
|
Popularity:
Describes how popular the package is relative to other packages.
[more]
|
97
|
Health:
Code health derived from static analysis.
[more]
|
--
|
Maintenance:
Reflects how tidy and up-to-date the package is.
[more]
|
--
|
Overall:
Weighted score of the above.
[more]
|
48
|
The package version is not analyzed, because it does not support Dart 2. Until this is resolved, the package will receive a health and maintenance score of 0.
Support Dart 2 in pubspec.yaml
.
The SDK constraint in pubspec.yaml
doesn't allow the Dart 2.0.0 release. For information about upgrading it to be Dart 2 compatible, please see https://www.dartlang.org/dart-2#migration.
Make sure dartdoc
successfully runs on your package's source files. (-10 points)
Running dartdoc
failed with the following output: