Flutter Google Map With Live Location Tracking — Uber Style
--
With this lesson, you will learn how to use Google Maps in Flutter with some customizations, like setting up Custom Image Markers and drawing route direction polylines. Add real-time location updates to the map.
Table of content ::
Initial Setup ⚙️
Google Map 🗺
Draw Route Direction 〰
Real-time Location Updates on Map 🔴
Add custom marker/pin 📍
Note: This post assumes you already have the maps set up in your project using the Google Maps Flutter Package and your own Google Maps API key. If not, follow this link on how to set up your Flutter project to work with Google Maps. Other dependencies include the Flutter Polyline Points package and the Flutter Location Plugin.
Initial Setup ⚙️
Make sure you prep your environment accordingly to enable location tracking on both IOS and Android by following the steps in the package’s README regarding the Android manifest file and the iOS Info.plist.
Once set up, the dependences look like 👇
....
dependencies:
flutter:
sdk: flutter
cupertino_icons: ^1.0.2
flutter_polyline_points: ^1.0.0
google_maps_flutter: ^2.1.7
location: ^4.4.0
...
Note: As of this writing, the versions of the packages above were the ones available — please update accordingly.
Google Map 🗺
Create a StatefulWidget called OrderTrackingPage with its corresponding State class, where I imported the required packages as well as some hardcoded source and destination location (for the sake of this tutorial).
import 'dart:async';
import 'package:flutter/material.dart';
import 'package:google_maps_flutter/google_maps_flutter.dart';class OrderTrackingPage extends StatefulWidget {
const OrderTrackingPage({Key? key}) : super(key: key);@override
State<OrderTrackingPage> createState() => OrderTrackingPageState();
}class OrderTrackingPageState extends State<OrderTrackingPage> {
final Completer<GoogleMapController> _controller = Completer();static const LatLng sourceLocation = LatLng(37.33500926, -122.03272188);
static const LatLng destination = LatLng(37.33429383, -122.06600055);@override
Widget build(BuildContext context) {
return Scaffold(
body: ... GoogleMap widget will be here ...,
);
}
}
Create the GoogleMap
widget and set the initialCameraPosition
to the location of the source. The map needs to be zoomed in a bit, so set it to 13.5.
We need a marker/pin to understand the exact location. Define a marker and set its position to the source location. For the destination, add another marker/pin.
GoogleMap(
initialCameraPosition: const CameraPosition(
target: sourceLocation,
zoom: 13.5,
),
markers: {
const Marker(
markerId: MarkerId("source"),
position: sourceLocation,
),
const Marker(
markerId: MarkerId("destination"),
position: destination,
),
},
onMapCreated: (mapController) {
_controller.complete(mapController);
},
),
Draw Route Direction 〰
The next thing I want to do is draw a line from destination to source. Create an empty list called polylineCoordinates
. Create an instance of PolylinePoints and an async function called getPolyPoints
. The method getRouteBetweenCoordinates
returns the list of polyline points. The Google API key, source, and destination locations were required. If the points are not empty, we store them to polylineCoordinates
.
List<LatLng> polylineCoordinates = [];void getPolyPoints() async {
PolylinePoints polylinePoints = PolylinePoints();PolylineResult result = await polylinePoints.getRouteBetweenCoordinates(
google_api_key, // Your Google Map Key
PointLatLng(sourceLocation.latitude, sourceLocation.longitude),
PointLatLng(destination.latitude, destination.longitude),
);if (result.points.isNotEmpty) {
result.points.forEach(
(PointLatLng point) => polylineCoordinates.add(
LatLng(point.latitude, point.longitude),
),
);
setState(() {});
}
}
On initState call
getPolyPoints
@override
void initState() {
getPolyPoints();
super.initState();
}
Back to the GoogleMap
widget, define the polylines.
GoogleMap(... polylines: {
Polyline(
polylineId: const PolylineId("route"),
points: polylineCoordinates,
color: const Color(0xFF7B61FF),
width: 6,
),
},
),
Real-time Location Updates on Map 🔴
Now come to the most exciting part, we need the device’s location. Create a nullable variable called currentLocation
. Then a function called getCurrentLocation
, Inside, creates an instance of Location
. Once we get the location, set the current location to be equal to the location. On location change, update the current location. Make it visible to the map called setState.
LocationData? currentLocation;void getCurrentLocation() async {
Location location = Location();location.getLocation().then(
(location) {
currentLocation = location;
},
);GoogleMapController googleMapController = await _controller.future;location.onLocationChanged.listen(
(newLoc) {
currentLocation = newLoc;googleMapController.animateCamera(
CameraUpdate.newCameraPosition(
CameraPosition(
zoom: 13.5,
target: LatLng(
newLoc.latitude!,
newLoc.longitude!,
),
),
),
);setState(() {});
},
);
}
Make sure to call the getCurrentLocation
on initState.
void initState() {
getPolyPoints();
getCurrentLocation();
super.initState();
}
If the currentLocation
is null, it shows a loading text. Also, add another marker/pin for the currentLocation
as well as change the initial camera position to the current location.
Complete body 👇
body: currentLocation == null
? const Center(child: Text("Loading"))
: GoogleMap(
initialCameraPosition: CameraPosition(
target: LatLng(
currentLocation!.latitude!, currentLocation!.longitude!),
zoom: 13.5,
),
markers: {
Marker(
markerId: const MarkerId("currentLocation"),
position: LatLng(
currentLocation!.latitude!, currentLocation!.longitude!),
),
const Marker(
markerId: MarkerId("source"),
position: sourceLocation,
),
const Marker(
markerId: MarkerId("destination"),
position: destination,
),
},
onMapCreated: (mapController) {
_controller.complete(mapController);
},
polylines: {
Polyline(
polylineId: const PolylineId("route"),
points: polylineCoordinates,
color: const Color(0xFF7B61FF),
width: 6,
),
},
),
Note: To simulate the location , you need to do some modifications.
For iOS ::
Go to Features, hover over location
, select Freeway drive
. I’m using source & destination location according to this Freeway drive.
For Android ::
If you are on Windows or using an Android simulator, click on the bottom three dots and ensure you are on location. Let’s say the source location is Google Plex, change the sourceLocation
to this coordinate and the destination location is the Microsoft silicon valley campus. Change the destination
with this location. Now click on the “routes” tab, and search for Microsoft silicon valley and Google plex for starting point. Save the route, set a playback speed hit play route. The current location is moving that’s what we want.
static const LatLng sourceLocation = your chosen locationstatic const LatLng destination = your chosen location
Add custom Marker/Pin 📍
The source, destination, and current location icons are the same. Let’s use a custom marker/pin for them.
BitmapDescriptor sourceIcon = BitmapDescriptor.defaultMarker;
BitmapDescriptor destinationIcon = BitmapDescriptor.defaultMarker;
BitmapDescriptor currentLocationIcon = BitmapDescriptor.defaultMarker;void setCustomMarkerIcon() {
BitmapDescriptor.fromAssetImage(
ImageConfiguration.empty, "assets/Pin_source.png")
.then(
(icon) {
sourceIcon = icon;
},
);
BitmapDescriptor.fromAssetImage(
ImageConfiguration.empty, "assets/Pin_destination.png")
.then(
(icon) {
destinationIcon = icon;
},
);
BitmapDescriptor.fromAssetImage(
ImageConfiguration.empty, "assets/Badge.png")
.then(
(icon) {
currentLocationIcon = icon;
},
);
}
Call setCustomMarkerIcon on initState
void initState() {
getPolyPoints();
getCurrentLocation();
setCustomMarkerIcon();
super.initState();
}
The final touch, on the marker set icon.
GoogleMap(.... markers: {
Marker(
markerId: const MarkerId("currentLocation"),
icon: currentLocationIcon,
position: LatLng(
currentLocation!.latitude!, currentLocation!.longitude!),
),
Marker(
markerId: const MarkerId("source"),
icon: sourceIcon,
position: sourceLocation,
),
Marker(
markerId: MarkerId("destination"),
icon: destinationIcon,
position: destination,
),
},
),
Video tutorial 🎬
Complet source code 🔥
Bonus 🥳 Shop UI Kit
❤ ❤ Thanks for reading this article ❤❤
If I got something wrong? Let me know in the comments. I would love to improve.
Clap 👏 If this article helps you.