1. Pengantar
Flutter adalah SDK aplikasi seluler Google untuk membuat pengalaman native berkualitas tinggi di iOS dan Android dalam waktu singkat.
Dengan plugin Google Maps Flutter, Anda dapat menambahkan peta ke aplikasi berdasarkan data peta Google. Plugin ini akan otomatis menangani akses ke server Google Maps, tampilan peta, dan respons terhadap gestur pengguna seperti klik dan tarik. Anda juga dapat menambahkan penanda ke peta. Objek ini memberikan informasi tambahan untuk lokasi peta, dan memungkinkan pengguna berinteraksi dengan peta.
Yang akan Anda buat
Dalam codelab ini, Anda akan mem-build aplikasi seluler yang dilengkapi Peta Google menggunakan Flutter SDK. Aplikasi Anda akan:
|
Apa itu Flutter?
Flutter memiliki tiga kemampuan inti.
- Dapat dikembangkan dengan cepat: Mem-build aplikasi Android dan iOS dalam hitungan milidetik dengan Stateful Hot Reload.
- Ekspresif dan fleksibel: Dengan cepat mengirim fitur yang berfokus pada pengalaman native pengguna akhir.
- Performa native di iOS dan Android: Widget Flutter mempertimbangkan semua perbedaan platform yang penting — seperti scroll, navigasi, ikon, dan font — untuk memberikan performa native yang lengkap.
Google Maps memiliki:
- Cakupan dunia seluas 99%: Melakukan build dengan data yang andal dan komprehensif untuk lebih dari 200 negara dan wilayah.
- 25 juta update setiap hari: Mengandalkan informasi lokasi real time yang akurat.
- 1 miliar pengguna aktif bulanan: Melakukan penskalaan dengan pasti, yang didukung oleh infrastruktur Google Maps.
Codelab ini memandu Anda dalam membuat pengalaman Google Maps di aplikasi Flutter untuk iOS dan Android.
Yang akan Anda pelajari
- Cara membuat aplikasi Flutter baru.
- Cara mengonfigurasi plugin Google Maps Flutter.
- Cara menambahkan Penanda ke peta, menggunakan data lokasi dari layanan web.
Codelab ini berfokus untuk menambahkan peta Google ke aplikasi Flutter. Konsep dan blok kode yang tidak relevan akan dibahas sekilas dan disediakan bagi Anda untuk disalin dan ditempelkan dengan mudah.
Apa yang ingin Anda pelajari dari codelab ini?
2. Menyiapkan lingkungan Flutter Anda
Anda memerlukan dua software untuk menyelesaikan lab ini: Flutter SDK dan editor. Codelab ini mengasumsikan bahwa pembaca akan menggunakan Android Studio, tetapi Anda dapat menggunakan editor pilihan sendiri.
Anda dapat menjalankan codelab ini menggunakan perangkat berikut:
- Perangkat fisik (Android atau iOS) yang terhubung ke komputer Anda dan ditetapkan ke mode developer.
- Simulator iOS: (Memerlukan penginstalan alat Xcode.)
- Android Emulator. (Memerlukan penyiapan di Android Studio.)
3. Memulai
Mulai menggunakan Flutter
Cara termudah untuk mulai menggunakan Flutter adalah dengan memanfaatkan alat command line flutter untuk membuat semua kode yang diperlukan untuk pengalaman penggunaan awal yang sederhana.
$ flutter create google_maps_in_flutter Creating project google_maps_in_flutter... [Listing of created files elided] Wrote 127 files. All done! In order to run your application, type: $ cd google_maps_in_flutter $ flutter run Your application code is in google_maps_in_flutter/lib/main.dart.
Menambahkan plugin Google Maps Flutter sebagai dependensi
Menambahkan kemampuan tambahan ke aplikasi Flutter mudah dilakukan menggunakan paket Pub. Dalam codelab ini, Anda akan menerapkan plugin Google Maps Flutter dengan menjalankan perintah berikut dari direktori project.
$ cd google_maps_in_flutter $ flutter pub add google_maps_flutter Resolving dependencies... async 2.6.1 (2.8.2 available) charcode 1.2.0 (1.3.1 available) + flutter_plugin_android_lifecycle 2.0.3 + google_maps_flutter 2.0.8 + google_maps_flutter_platform_interface 2.1.1 matcher 0.12.10 (0.12.11 available) meta 1.3.0 (1.7.0 available) + plugin_platform_interface 2.0.1 + stream_transform 2.0.0 test_api 0.3.0 (0.4.3 available) Downloading google_maps_flutter 2.0.8... Downloading flutter_plugin_android_lifecycle 2.0.3... Changed 5 dependencies!
Codelab ini juga akan membahas cara menggunakan Google Maps di Flutter untuk Web. Namun, versi Web plugin ini belum difederasi, jadi Anda juga perlu menambahkannya ke project.
$ flutter pub add google_maps_flutter_web Resolving dependencies... async 2.6.1 (2.8.2 available) charcode 1.2.0 (1.3.1 available) + csslib 0.17.0 + flutter_web_plugins 0.0.0 from sdk flutter + google_maps 5.3.0 + google_maps_flutter_web 0.3.0+4 + html 0.15.0 + js 0.6.3 + js_wrapping 0.7.3 matcher 0.12.10 (0.12.11 available) meta 1.3.0 (1.7.0 available) + sanitize_html 2.0.0 test_api 0.3.0 (0.4.3 available) Changed 8 dependencies!
Mengonfigurasi platform
iOS
Untuk mendapatkan versi terbaru Google Maps SDK di iOS, Anda memerlukan versi minimum platform iOS 11. Ubah ios/Podfile sebagai berikut.
ios/Podfile
# Set platform to 11.0 to enable latest Google Maps SDK
platform :ios, '11.0' # Uncomment and set to 11.
# CocoaPods analytics sends network stats synchronously affecting flutter build latency.
ENV['COCOAPODS_DISABLE_STATS'] = 'true'
Mengonfigurasi minSDK
Android
Untuk menggunakan Google Maps SDK di Android, tetapkan minSDK
ke 20. Ubah android/app/build.gradle sebagai berikut.
android/app/build.gradle
android {
defaultConfig {
// TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html).
applicationId "com.example.google_maps_in_flutter"
minSdkVersion 20 // Update from 16 to 20
targetSdkVersion 30
versionCode flutterVersionCode.toInteger()
versionName flutterVersionName
}
}
4. Menambahkan Google Maps ke aplikasi
Tentang kunci API
Untuk menjalankan Google Maps di aplikasi Flutter, Anda perlu mengonfigurasi project API menggunakan Google Maps Platform, dengan mengikuti petunjuk dalam artikel Menggunakan kunci API (Maps SDK for Android), Menggunakan kunci API (Maps SDK untuk iOS), dan Menggunakan kunci API (Maps JavaScript API). Setelah memiliki kunci API, lakukan langkah-langkah berikut untuk mengonfigurasi aplikasi Android dan iOS.
Menambahkan kunci API untuk aplikasi Android
Untuk menambahkan kunci API ke aplikasi Android, edit file AndroidManifest.xml
di android/app/src/main
. Tambahkan satu entri meta-data
yang berisi kunci API yang dibuat pada langkah sebelumnya di dalam node application
.
android/app/src/main/AndroidManifest.xml
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.google_maps_in_flutter">
<application
android:label="google_maps_in_flutter"
android:icon="@mipmap/ic_launcher">
<!-- TODO: Add your Google Maps API key here -->
<meta-data android:name="com.google.android.geo.API_KEY"
android:value="YOUR-KEY-HERE"/>
<activity
android:name=".MainActivity"
android:launchMode="singleTop"
android:theme="@style/LaunchTheme"
android:configChanges="orientation|keyboardHidden|keyboard|screenSize|smallestScreenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode"
android:hardwareAccelerated="true"
android:windowSoftInputMode="adjustResize">
<meta-data
android:name="io.flutter.embedding.android.NormalTheme"
android:resource="@style/NormalTheme"
/>
<meta-data
android:name="io.flutter.embedding.android.SplashScreenDrawable"
android:resource="@drawable/launch_background"
/>
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
</activity>
<meta-data
android:name="flutterEmbedding"
android:value="2" />
</application>
</manifest>
Menambahkan kunci API untuk aplikasi iOS
Untuk menambahkan kunci API ke aplikasi iOS, edit file AppDelegate.swift
di ios/Runner
. Tidak seperti Android, untuk menambahkan kunci API di iOS, Anda harus mengubah kode sumber aplikasi Runner. AppDelegate adalah singleton inti yang merupakan bagian dari proses inisialisasi aplikasi.
Buat dua perubahan pada file ini. Pertama, tambahkan pernyataan #import
untuk menarik header Google Maps, lalu panggil metode provideAPIKey()
untuk singleton GMSServices
. Dengan kunci API ini, Google Maps dapat menampilkan ubin peta dengan benar.
ios/Runner/AppDelegate.swift
import UIKit
import Flutter
import GoogleMaps // Add this import
@UIApplicationMain
@objc class AppDelegate: FlutterAppDelegate {
override func application(
_ application: UIApplication,
didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
) -> Bool {
GeneratedPluginRegistrant.register(with: self)
// TODO: Add your Google Maps API key
GMSServices.provideAPIKey("YOUR-API-KEY")
return super.application(application, didFinishLaunchingWithOptions: launchOptions)
}
}
Menambahkan kunci API untuk aplikasi Web
Untuk menambahkan kunci API ke aplikasi Web, edit file index.html
di web
. Tambahkan referensi ke skrip Maps JavaScript di bagian head, dengan kunci API Anda.
web/index.html
<head>
<base href="/">
<meta charset="UTF-8">
<meta content="IE=Edge" http-equiv="X-UA-Compatible">
<meta name="description" content="A new Flutter project.">
<!-- iOS meta tags & icons -->
<meta name="apple-mobile-web-app-capable" content="yes">
<meta name="apple-mobile-web-app-status-bar-style" content="black">
<meta name="apple-mobile-web-app-title" content="google_maps_in_flutter">
<link rel="apple-touch-icon" href="icons/Icon-192.png">
<!-- TODO: Add your Google Maps API key here -->
<script src="https://maps.googleapis.com/maps/api/js?key=YOUR-KEY-HERE"></script>
<title>google_maps_in_flutter</title>
<link rel="manifest" href="manifest.json">
</head>
Menampilkan peta di layar
Sekarang saatnya menampilkan peta di layar. Update lib/main.dart
sebagai berikut:
lib/main.dart
import 'package:flutter/material.dart';
import 'package:google_maps_flutter/google_maps_flutter.dart';
void main() => runApp(const MyApp());
class MyApp extends StatefulWidget {
const MyApp({Key? key}) : super(key: key);
@override
_MyAppState createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
late GoogleMapController mapController;
final LatLng _center = const LatLng(45.521563, -122.677433);
void _onMapCreated(GoogleMapController controller) {
mapController = controller;
}
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: const Text('Maps Sample App'),
backgroundColor: Colors.green[700],
),
body: GoogleMap(
onMapCreated: _onMapCreated,
initialCameraPosition: CameraPosition(
target: _center,
zoom: 11.0,
),
),
),
);
}
}
Menjalankan aplikasi
Jalankan aplikasi Flutter di iOS atau Android untuk melihat satu tampilan peta, yang berpusat di Portland. Atau, jalankan Android Emulator atau simulator iOS. Jika ingin, ubah pusat peta untuk menampilkan kota asal Anda, atau tempat mana pun yang penting bagi Anda.
$ flutter run
5. Menempatkan Google di Peta
Google memiliki banyak kantor di seluruh dunia, mulai dari Amerika Utara, Amerika Latin, Eropa, Asia Pasifik, hingga Afrika & Timur Tengah. Jika Anda mempelajarinya, peta ini memiliki fungsi yang praktis, yaitu endpoint API yang mudah digunakan untuk menyediakan informasi lokasi kantor dalam format JSON. Pada langkah ini, Anda akan menempatkan lokasi kantor tersebut di peta. Pada langkah ini, Anda akan menggunakan pembuatan kode untuk menguraikan JSON.
Tambahkan tiga dependensi Flutter baru ke project sebagai berikut. Pertama, tambahkan paket http
untuk membuat permintaan HTTP dengan mudah.
$ flutter pub add http Resolving dependencies... async 2.8.1 (2.8.2 available) + http 0.13.3 + http_parser 4.0.0 matcher 0.12.10 (0.12.11 available) + pedantic 1.11.1 test_api 0.4.2 (0.4.3 available) Changed 3 dependencies!
Selanjutnya, tambahkan json_serializable untuk mendeklarasikan struktur objek agar merepresentasikan dokumen JSON.
$ flutter pub add json_serializable Resolving dependencies... + _fe_analyzer_shared 25.0.0 + analyzer 2.2.0 + args 2.2.0 async 2.8.1 (2.8.2 available) + build 2.1.0 + build_config 1.0.0 + checked_yaml 2.0.1 + cli_util 0.3.3 + convert 3.0.1 + crypto 3.0.1 + dart_style 2.0.3 + file 6.1.2 + glob 2.0.1 + json_annotation 4.1.0 + json_serializable 5.0.0 + logging 1.0.1 matcher 0.12.10 (0.12.11 available) + package_config 2.0.0 + pub_semver 2.0.0 + pubspec_parse 1.0.0 + source_gen 1.1.0 + source_helper 1.2.1 test_api 0.4.2 (0.4.3 available) + watcher 1.0.0 + yaml 3.1.0 Downloading analyzer 2.2.0... Downloading _fe_analyzer_shared 25.0.0... Changed 22 dependencies!
Terakhir, tambahkan build_runner sebagai dependensi waktu pengembangan. Hal ini akan digunakan untuk pembuatan kode nanti di langkah ini.
$ flutter pub add --dev build_runner Resolving dependencies... async 2.8.1 (2.8.2 available) + build_daemon 3.0.0 + build_resolvers 2.0.4 + build_runner 2.1.1 + build_runner_core 7.1.0 + built_collection 5.1.0 + built_value 8.1.2 + code_builder 4.1.0 + fixnum 1.0.0 + frontend_server_client 2.1.2 + graphs 2.0.0 + http_multi_server 3.0.1 + io 1.0.3 + js 0.6.3 matcher 0.12.10 (0.12.11 available) + mime 1.0.0 + pool 1.5.0 + shelf 1.2.0 + shelf_web_socket 1.0.1 test_api 0.4.2 (0.4.3 available) + timing 1.0.0 + web_socket_channel 2.1.0 Changed 19 dependencies!
Menguraikan JSON dengan pembuatan kode
Anda mungkin mendapati bahwa data JSON yang ditampilkan dari endpoint API memiliki struktur biasa. Akan lebih praktis jika Anda membuat kode untuk mengarahkan data tersebut ke objek yang dapat digunakan dalam kode.
Dalam direktori lib/src
, buat file locations.dart
dan deskripsikan struktur data JSON yang ditampilkan sebagai berikut:
lib/src/locations.dart
import 'dart:convert';
import 'package:http/http.dart' as http;
import 'package:json_annotation/json_annotation.dart';
import 'package:flutter/services.dart' show rootBundle;
part 'locations.g.dart';
@JsonSerializable()
class LatLng {
LatLng({
required this.lat,
required this.lng,
});
factory LatLng.fromJson(Map<String, dynamic> json) => _$LatLngFromJson(json);
Map<String, dynamic> toJson() => _$LatLngToJson(this);
final double lat;
final double lng;
}
@JsonSerializable()
class Region {
Region({
required this.coords,
required this.id,
required this.name,
required this.zoom,
});
factory Region.fromJson(Map<String, dynamic> json) => _$RegionFromJson(json);
Map<String, dynamic> toJson() => _$RegionToJson(this);
final LatLng coords;
final String id;
final String name;
final double zoom;
}
@JsonSerializable()
class Office {
Office({
required this.address,
required this.id,
required this.image,
required this.lat,
required this.lng,
required this.name,
required this.phone,
required this.region,
});
factory Office.fromJson(Map<String, dynamic> json) => _$OfficeFromJson(json);
Map<String, dynamic> toJson() => _$OfficeToJson(this);
final String address;
final String id;
final String image;
final double lat;
final double lng;
final String name;
final String phone;
final String region;
}
@JsonSerializable()
class Locations {
Locations({
required this.offices,
required this.regions,
});
factory Locations.fromJson(Map<String, dynamic> json) =>
_$LocationsFromJson(json);
Map<String, dynamic> toJson() => _$LocationsToJson(this);
final List<Office> offices;
final List<Region> regions;
}
Future<Locations> getGoogleOffices() async {
const googleLocationsURL = 'https://about.google/static/data/locations.json';
// Retrieve the locations of Google offices
try {
final response = await http.get(Uri.parse(googleLocationsURL));
if (response.statusCode == 200) {
return Locations.fromJson(json.decode(response.body));
}
} catch (e) {
print(e);
}
// Fallback for when the above HTTP request fails.
return Locations.fromJson(
json.decode(
await rootBundle.loadString('assets/locations.json'),
),
);
}
Setelah menambahkan kode ini, IDE (jika Anda menggunakannya) akan menampilkan beberapa garis bergelombang merah, karena IDE ini merujuk ke file seinduk yang tidak ada, locations.g.dart.
File yang dihasilkan ini dikonversi antara struktur JSON tidak bertipe dan objek bernama. Buat file tersebut dengan menjalankan build_runner
:
$ flutter pub run build_runner build --delete-conflicting-outputs [INFO] Generating build script... [INFO] Generating build script completed, took 357ms [INFO] Creating build script snapshot...... [INFO] Creating build script snapshot... completed, took 10.5s [INFO] There was output on stdout while compiling the build script snapshot, run with `--verbose` to see it (you will need to run a `clean` first to re-snapshot). [INFO] Initializing inputs [INFO] Building new asset graph... [INFO] Building new asset graph completed, took 646ms [INFO] Checking for unexpected pre-existing outputs.... [INFO] Deleting 1 declared outputs which already existed on disk. [INFO] Checking for unexpected pre-existing outputs. completed, took 3ms [INFO] Running build... [INFO] Generating SDK summary... [INFO] 3.4s elapsed, 0/3 actions completed. [INFO] Generating SDK summary completed, took 3.4s [INFO] 4.7s elapsed, 2/3 actions completed. [INFO] Running build completed, took 4.7s [INFO] Caching finalized dependency graph... [INFO] Caching finalized dependency graph completed, took 36ms [INFO] Succeeded after 4.8s with 2 outputs (7 actions)
Sekarang, kode Anda seharusnya dianalisis kembali dengan rapi. Selanjutnya, kita harus menambahkan file fallback locations.json yang digunakan dalam fungsi getGoogleOffices
. Salah satu alasan menyertakan fallback ini adalah karena data statis yang dimuat dalam fungsi ini disajikan tanpa header CORS, sehingga akan gagal dimuat di browser web. Aplikasi Flutter versi Android dan iOS tidak memerlukan header CORS, tetapi akses data seluler dapat bermasalah bahkan dalam kondisi yang menguntungkan.
Buka https://about.google/static/data/locations.json
di browser Anda, lalu simpan kontennya ke dalam direktori aset. Atau, Anda dapat menggunakan command line sebagai berikut.
$ mkdir assets $ cd assets $ curl -o locations.json https://about.google/static/data/locations.json % Total % Received % Xferd Average Speed Time Time Time Current Dload Upload Total Spent Left Speed 100 30348 100 30348 0 0 75492 0 --:--:-- --:--:-- --:--:-- 75492
Setelah file aset didownload, tambahkan file tersebut ke bagian flutter di file pubspec.yaml
Anda.
pubspec.yaml
flutter:
uses-material-design: true
assets:
- assets/locations.json
Ubah file main.dart
untuk meminta data peta, lalu gunakan info yang ditampilkan untuk menambahkan kantor ke peta:
lib/main.dart
import 'package:flutter/material.dart';
import 'package:google_maps_flutter/google_maps_flutter.dart';
import 'src/locations.dart' as locations;
void main() {
runApp(const MyApp());
}
class MyApp extends StatefulWidget {
const MyApp({Key? key}) : super(key: key);
@override
_MyAppState createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
final Map<String, Marker> _markers = {};
Future<void> _onMapCreated(GoogleMapController controller) async {
final googleOffices = await locations.getGoogleOffices();
setState(() {
_markers.clear();
for (final office in googleOffices.offices) {
final marker = Marker(
markerId: MarkerId(office.name),
position: LatLng(office.lat, office.lng),
infoWindow: InfoWindow(
title: office.name,
snippet: office.address,
),
);
_markers[office.name] = marker;
}
});
}
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: const Text('Google Office Locations'),
backgroundColor: Colors.green[700],
),
body: GoogleMap(
onMapCreated: _onMapCreated,
initialCameraPosition: const CameraPosition(
target: LatLng(0, 0),
zoom: 2,
),
markers: _markers.values.toSet(),
),
),
);
}
}
Kode ini melakukan beberapa operasi:
- Di
_onMapCreated
, kode ini menggunakan kode penguraian JSON dari langkah sebelumnya. Statusawait
akan ditampilkan sampai kode ini dimuat. Kemudian, kode ini akan menggunakan data yang ditampilkan untuk membuatMarker
di dalam callbacksetState()
. Setelah aplikasi menerima penanda baru, setState akan memberi tahu Flutter untuk melakukan repaint layar, yang menyebabkan lokasi kantor ditampilkan. - Penanda disimpan dalam
Map
yang terkait dengan widgetGoogleMap
. Tindakan ini akan menautkan penanda ke peta yang benar. Tentu saja, Anda dapat memiliki beberapa peta dan menampilkan penanda yang berbeda-beda di setiap peta.
Berikut screenshot yang menampilkan hal yang telah Anda capai. Ada banyak tambahan menarik yang dapat dibuat pada tahap ini. Misalnya, Anda dapat menambahkan tampilan daftar kantor yang menggerakkan dan melakukan zoom pada peta saat pengguna mengklik sebuah kantor, tetapi hal ini bersifat opsional bagi pembaca.
6. Langkah berikutnya
Selamat.
Anda telah menyelesaikan codelab dan mem-build aplikasi Flutter dengan Google Map. Anda juga telah berinteraksi dengan Layanan Web JSON.
Langkah berikutnya yang lain
Codelab ini telah menciptakan pengalaman untuk memvisualisasikan sejumlah titik pada peta. Ada sejumlah aplikasi seluler yang memanfaatkan kemampuan ini untuk memenuhi berbagai kebutuhan pengguna. Berikut referensi lainnya dapat membantu Anda lebih lanjut:
- Build Mobile Apps With Flutter and Google Maps (penjelasan yang disampaikan di Cloud Next ‘19)
- Paket
google_maps_webservice
Hadrien Lejard yang sangat memudahkan penggunaan Layanan Web Google Maps, seperti Directions API, Distance Matrix API, dan Places API. - Jika Anda ingin mengamati berbagai opsi penggunaan API melalui REST JSON, lihat postingan Medium Andrew Brogdon untuk mengetahui beragam opsi dalam menggunakan REST API JSON.