├── .fvmrc ├── .gitignore ├── .metadata ├── .vscode └── settings.json ├── CHANGELOG.md ├── LICENSE ├── README.md ├── analysis_options.yaml ├── example ├── .fvmrc ├── .gitignore ├── .metadata ├── README.md ├── analysis_options.yaml ├── android │ ├── .gitignore │ ├── app │ │ ├── build.gradle │ │ └── src │ │ │ ├── debug │ │ │ └── AndroidManifest.xml │ │ │ ├── main │ │ │ ├── AndroidManifest.xml │ │ │ ├── kotlin │ │ │ │ └── com │ │ │ │ │ └── example │ │ │ │ │ └── google_maps_widget_demo │ │ │ │ │ └── MainActivity.kt │ │ │ └── res │ │ │ │ ├── drawable-v21 │ │ │ │ └── launch_background.xml │ │ │ │ ├── drawable │ │ │ │ └── launch_background.xml │ │ │ │ ├── mipmap-hdpi │ │ │ │ └── ic_launcher.png │ │ │ │ ├── mipmap-mdpi │ │ │ │ └── ic_launcher.png │ │ │ │ ├── mipmap-xhdpi │ │ │ │ └── ic_launcher.png │ │ │ │ ├── mipmap-xxhdpi │ │ │ │ └── ic_launcher.png │ │ │ │ ├── mipmap-xxxhdpi │ │ │ │ └── ic_launcher.png │ │ │ │ ├── values-night │ │ │ │ └── styles.xml │ │ │ │ └── values │ │ │ │ └── styles.xml │ │ │ └── profile │ │ │ └── AndroidManifest.xml │ ├── build.gradle │ ├── gradle.properties │ ├── gradle │ │ └── wrapper │ │ │ └── gradle-wrapper.properties │ └── settings.gradle ├── assets │ └── images │ │ ├── driver-marker-icon.png │ │ ├── house-marker-icon.png │ │ └── restaurant-marker-icon.png ├── ios │ ├── .gitignore │ ├── Flutter │ │ ├── AppFrameworkInfo.plist │ │ ├── Debug.xcconfig │ │ └── Release.xcconfig │ ├── Podfile │ ├── Runner.xcodeproj │ │ ├── project.pbxproj │ │ ├── project.xcworkspace │ │ │ ├── contents.xcworkspacedata │ │ │ └── xcshareddata │ │ │ │ ├── IDEWorkspaceChecks.plist │ │ │ │ └── WorkspaceSettings.xcsettings │ │ └── xcshareddata │ │ │ └── xcschemes │ │ │ └── Runner.xcscheme │ ├── Runner.xcworkspace │ │ ├── contents.xcworkspacedata │ │ └── xcshareddata │ │ │ ├── IDEWorkspaceChecks.plist │ │ │ └── WorkspaceSettings.xcsettings │ ├── Runner │ │ ├── AppDelegate.m │ │ ├── AppDelegate.swift │ │ ├── Assets.xcassets │ │ │ ├── AppIcon.appiconset │ │ │ │ ├── Contents.json │ │ │ │ ├── Icon-App-1024x1024@1x.png │ │ │ │ ├── Icon-App-20x20@1x.png │ │ │ │ ├── Icon-App-20x20@2x.png │ │ │ │ ├── Icon-App-20x20@3x.png │ │ │ │ ├── Icon-App-29x29@1x.png │ │ │ │ ├── Icon-App-29x29@2x.png │ │ │ │ ├── Icon-App-29x29@3x.png │ │ │ │ ├── Icon-App-40x40@1x.png │ │ │ │ ├── Icon-App-40x40@2x.png │ │ │ │ ├── Icon-App-40x40@3x.png │ │ │ │ ├── Icon-App-60x60@2x.png │ │ │ │ ├── Icon-App-60x60@3x.png │ │ │ │ ├── Icon-App-76x76@1x.png │ │ │ │ ├── Icon-App-76x76@2x.png │ │ │ │ └── Icon-App-83.5x83.5@2x.png │ │ │ └── LaunchImage.imageset │ │ │ │ ├── Contents.json │ │ │ │ ├── LaunchImage.png │ │ │ │ ├── LaunchImage@2x.png │ │ │ │ ├── LaunchImage@3x.png │ │ │ │ └── README.md │ │ ├── Base.lproj │ │ │ ├── LaunchScreen.storyboard │ │ │ └── Main.storyboard │ │ ├── Info.plist │ │ └── Runner-Bridging-Header.h │ └── RunnerTests │ │ └── RunnerTests.swift ├── lib │ └── main.dart ├── pubspec.lock └── pubspec.yaml ├── lib ├── google_maps_widget.dart └── src │ ├── main_widget.dart │ ├── models │ ├── direction.dart │ └── marker_icon_info.dart │ └── utils │ └── constants.dart ├── pubspec.lock └── pubspec.yaml /.fvmrc: -------------------------------------------------------------------------------- 1 | { 2 | "flutter": "3.24.3" 3 | } -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Miscellaneous 2 | *.class 3 | *.log 4 | *.pyc 5 | *.swp 6 | .DS_Store 7 | .atom/ 8 | .buildlog/ 9 | .history 10 | .svn/ 11 | 12 | # IntelliJ related 13 | *.iml 14 | *.ipr 15 | *.iws 16 | .idea/ 17 | 18 | # The .vscode folder contains launch configuration and tasks you configure in 19 | # VS Code which you may wish to be included in version control, so this line 20 | # is commented out by default. 21 | #.vscode/ 22 | 23 | # Flutter/Dart/Pub related 24 | **/doc/api/ 25 | .dart_tool/ 26 | .flutter-plugins 27 | .flutter-plugins-dependencies 28 | .packages 29 | .pub-cache/ 30 | .pub/ 31 | build/ 32 | 33 | # Android related 34 | **/android/**/gradle-wrapper.jar 35 | **/android/.gradle 36 | **/android/captures/ 37 | **/android/gradlew 38 | **/android/gradlew.bat 39 | **/android/local.properties 40 | **/android/**/GeneratedPluginRegistrant.java 41 | 42 | # iOS/XCode related 43 | **/ios/**/*.mode1v3 44 | **/ios/**/*.mode2v3 45 | **/ios/**/*.moved-aside 46 | **/ios/**/*.pbxuser 47 | **/ios/**/*.perspectivev3 48 | **/ios/**/*sync/ 49 | **/ios/**/.sconsign.dblite 50 | **/ios/**/.tags* 51 | **/ios/**/.vagrant/ 52 | **/ios/**/DerivedData/ 53 | **/ios/**/Icon? 54 | **/ios/**/Pods/ 55 | **/ios/**/.symlinks/ 56 | **/ios/**/profile 57 | **/ios/**/xcuserdata 58 | **/ios/.generated/ 59 | **/ios/Flutter/App.framework 60 | **/ios/Flutter/Flutter.framework 61 | **/ios/Flutter/Flutter.podspec 62 | **/ios/Flutter/Generated.xcconfig 63 | **/ios/Flutter/app.flx 64 | **/ios/Flutter/app.zip 65 | **/ios/Flutter/flutter_assets/ 66 | **/ios/Flutter/flutter_export_environment.sh 67 | **/ios/ServiceDefinitions.json 68 | **/ios/Runner/GeneratedPluginRegistrant.* 69 | 70 | # Exceptions to above rules. 71 | !**/ios/**/default.mode1v3 72 | !**/ios/**/default.mode2v3 73 | !**/ios/**/default.pbxuser 74 | !**/ios/**/default.perspectivev3 75 | 76 | # FVM Version Cache 77 | .fvm/ -------------------------------------------------------------------------------- /.metadata: -------------------------------------------------------------------------------- 1 | # This file tracks properties of this Flutter project. 2 | # Used by Flutter tool to assess capabilities and perform upgrades etc. 3 | # 4 | # This file should be version controlled and should not be manually edited. 5 | 6 | version: 7 | revision: b1395592de68cc8ac4522094ae59956dd21a91db 8 | channel: stable 9 | 10 | project_type: package 11 | -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "dart.flutterSdkPath": ".fvm/versions/3.24.3", 3 | "dart.lineLength": 80, 4 | "workbench.colorCustomizations": { 5 | "activityBar.background": "#482403", 6 | "titleBar.activeBackground": "#653204", 7 | "titleBar.activeForeground": "#FFFBF7" 8 | } 9 | } -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # [1.0.6] 2 | 3 | * FIX: Bug where `assetMarkerSize` in `MarkerIconInfo` does not apply if `icon` is passed. 4 | * Fix Dart static analysis warnings 5 | * Updated README.md 6 | * Updated example app 7 | * Updated dependencies 8 | 9 | # [1.0.5+1] 10 | 11 | * Updated README.md 12 | 13 | # [1.0.5] 14 | 15 | * BREAKING: `MarkerIconInfo` inputs are now non-nullable 16 | * BREAKING: Added properties `onTapMarker`, `onTapInfoWindow`, `infoWindowTitle` and `isVisible` to `MarkerIconInfo`, and removed corresponding params for source, destination, driver from `GoogleMapsWidget` 17 | * Changed internal implementation of the widget 18 | * Added `layoutDirection` property 19 | * Added `onPolylineUpdate` callback 20 | * Exposed state class to allow updating source/destination lat lng, or interacting with google maps con directly 21 | * Updated a dependency to the latest release 22 | * Updated example app 23 | * Updated README.md 24 | 25 | # [1.0.4] 26 | 27 | * Added updatePolylinesOnDriverLocUpdate to update directions based on current driver location 28 | * Updated dependencies 29 | * Updated example app 30 | * Updated README.md 31 | 32 | # [1.0.3] 33 | 34 | * Added rotation and anchor to MarkerIconInfo 35 | * Updated README.md 36 | 37 | # [1.0.2] 38 | 39 | * Updated dependencies 40 | * Updated linter warnings 41 | 42 | # [1.0.1] 43 | 44 | * Updated license 45 | * Updated README.md 46 | 47 | # [1.0.0] 48 | 49 | * Added linter and updated code accordingly 50 | * Updated dependencies 51 | * Removed unused dependencies 52 | * Updated README.md 53 | 54 | # [0.0.9] 55 | 56 | * Fixed issue #2 57 | 58 | # [0.0.8] 59 | 60 | * Fixed key parameter 61 | 62 | # [0.0.7] 63 | 64 | * Set of markers can be passed to show on the map (apart from the source/destination/driver markers). 65 | * Set of polylines can be passed to show on the map apart from the one created between source and destination. 66 | * Added the option to not render the created markers and polylines. 67 | 68 | # [0.0.6] 69 | 70 | * Updated README.md 71 | 72 | # [0.0.5] 73 | 74 | * Added web support 75 | 76 | # [0.0.4] 77 | 78 | * Added dart doc comments 79 | * Updated package description. 80 | * Updated README. 81 | * Updated example app 82 | 83 | # [0.0.3] 84 | 85 | * Updated package description. 86 | 87 | # [0.0.2] 88 | 89 | * Minor readme fixes. 90 | * Added package description. 91 | 92 | # [0.0.1] 93 | 94 | * A Google Maps helper widget which can be used to draw route from a given source latitude and longitude. The route is customizable in terms of color and width. 95 | * The plugin also offers realtime location tracking for a driver(if any) and shows a marker on the map which updates everytimes the driver's location changes. 96 | * The markers are customizable and on tap callbacks are implemented that give the current location and a lot of parameters which can be explored. 97 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2021 Rithik Bhandari 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # [GoogleMapsWidget](https://pub.dev/packages/google_maps_widget) For Flutter 2 | [![pub package](https://img.shields.io/pub/v/google_maps_widget.svg)](https://pub.dev/packages/google_maps_widget) 3 | [![likes](https://img.shields.io/pub/likes/google_maps_widget)](https://pub.dev/packages/google_maps_widget/score) 4 | [![popularity](https://img.shields.io/pub/popularity/google_maps_widget)](https://pub.dev/packages/google_maps_widget/score) 5 | [![pub points](https://img.shields.io/pub/points/google_maps_widget)](https://pub.dev/packages/google_maps_widget/score) 6 | [![code size](https://img.shields.io/github/languages/code-size/rithik-dev/google_maps_widget)](https://github.com/rithik-dev/google_maps_widget) 7 | [![license MIT](https://img.shields.io/badge/license-MIT-purple.svg)](https://opensource.org/licenses/MIT) 8 | 9 | --- 10 | 11 | A widget for flutter developers to easily integrate google maps in their apps. It can be used to make polylines from a source to a destination, and also handle a driver's realtime location (if any) on the map. 12 | 13 | --- 14 | 15 | # 🗂️ Table of Contents 16 | 17 | - **[📷 Screenshots](#-screenshots)** 18 | - **[✨ Features](#-features)** 19 | - **[🚀 Getting Started](#-getting-started)** 20 | - **[🛠️ Platform-specific Setup](#%EF%B8%8F-platform-specific-setup)** 21 | - [Android](#android) 22 | - [iOS](#ios) 23 | - [Web](#web) 24 | - **[❓ Usage](#-usage)** 25 | - **[🎯 Sample Usage](#-sample-usage)** 26 | - **[👤 Collaborators](#-collaborators)** 27 | 28 | --- 29 | 30 | # 📷 Screenshots 31 | 32 | | With Source InfoWindow | With Rider Icon | With Rider Icon InfoWindow | 33 | |-----------------------------------|-------------------------------------|-------------------------------------| 34 | | | | | 35 | 36 | --- 37 | 38 | # ✨ Features 39 | 40 | - **Route Creation:** Draw polylines (routes) between two locations by providing their latitude and longitude. 41 | - **Customizable Route Appearance:** Customize the route’s color and width. 42 | - **Real-time Location Tracking:** Offers real-time location tracking for drivers, with an automatically updating marker on the map as the driver's location changes. 43 | - **Marker Customization:** Fully customizable markers. 44 | - **User Interaction Handling:** onTap callbacks for all markers and info windows to handle user interactions easily. 45 | - **Full Google Maps Parameter Support:** Supports passing nearly all parameters from google_maps_flutter for the GoogleMap widget as arguments to the plugin. 46 | 47 | --- 48 | 49 | # 🚀 Getting Started 50 | 51 | ## Step 1: Get an API Key 52 | Visit [Google Cloud Maps Platform](https://cloud.google.com/maps-platform) and obtain an API key. 53 | 54 | ## Step 2: Enable Google Maps SDK for Each Platform and Directions API 55 | * Go to [Google Developers Console](https://console.cloud.google.com), select your project, and open the Google Maps section from the navigation menu. Under APIs, enable Maps SDK for Android, Maps SDK for iOS, and Maps JavaScript API for web under the "Additional APIs" section. 56 | 57 | * To enable Directions API, select "Directions API" in the "Additional APIs" section, then select "ENABLE". 58 | 59 | > [!NOTE] 60 | > Make sure the APIs you enabled are under the "Enabled APIs" section. 61 | 62 | ## Step 3: Refer the Documentation 63 | For more details, see [Getting started with Google Maps Platform](https://developers.google.com/maps/gmp-get-started). 64 | 65 | --- 66 | 67 | # 🛠️ Platform-Specific Setup 68 | 69 | ## Android 70 | > [!NOTE] 71 | > Refer to the platform specific setup for google maps [here](https://pub.dev/packages/google_maps_flutter#android) 72 | 73 | Specify your API key in the application manifest `android/app/src/main/AndroidManifest.xml`: 74 | 75 | ```xml 76 | 80 | ``` 81 | 82 | ## iOS 83 | > [!NOTE] 84 | > Refer to the platform specific setup for google maps [here](https://pub.dev/packages/google_maps_flutter#ios) 85 | 86 | Specify your API key in the application delegate `ios/Runner/AppDelegate.m`: 87 | 88 | ```objectivec 89 | #include "AppDelegate.h" 90 | #include "GeneratedPluginRegistrant.h" 91 | #import "GoogleMaps/GoogleMaps.h" 92 | 93 | @implementation AppDelegate 94 | 95 | - (BOOL)application:(UIApplication *)application 96 | didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { 97 | [GMSServices provideAPIKey:@"YOUR KEY HERE"]; 98 | [GeneratedPluginRegistrant registerWithRegistry:self]; 99 | return [super application:application didFinishLaunchingWithOptions:launchOptions]; 100 | } 101 | @end 102 | ``` 103 | 104 | Or in your swift code, specify your API key in the application delegate `ios/Runner/AppDelegate.swift`: 105 | 106 | ```swift 107 | import UIKit 108 | import Flutter 109 | import GoogleMaps 110 | 111 | @UIApplicationMain 112 | @objc class AppDelegate: FlutterAppDelegate { 113 | override func application( 114 | _ application: UIApplication, 115 | didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]? 116 | ) -> Bool { 117 | GMSServices.provideAPIKey("YOUR KEY HERE") 118 | GeneratedPluginRegistrant.register(with: self) 119 | return super.application(application, didFinishLaunchingWithOptions: launchOptions) 120 | } 121 | } 122 | ``` 123 | 124 | ## Web 125 | > [!NOTE] 126 | > Refer to the platform specific setup for google maps [here](https://pub.dev/packages/google_maps_flutter#web) 127 | 128 | Modify web/index.html 129 | 130 | Get an API Key for Google Maps JavaScript API. Get started [here](https://developers.google.com/maps/documentation/javascript/get-api-key). 131 | Modify the `` tag of your `web/index.html` to load the Google Maps JavaScript API, like so: 132 | ```html 133 | 134 | 135 | 136 | 137 | 138 | 139 | ``` 140 | 141 | --- 142 | 143 | # ❓ Usage 144 | 145 | 1. Add [`google_maps_widget`](https://pub.dev/packages/google_maps_widget) as a dependency in your pubspec.yaml file. 146 | ```yaml 147 | dependencies: 148 | flutter: 149 | sdk: flutter 150 | 151 | google_maps_widget: 152 | ``` 153 | 154 | 2. You can now add a [`GoogleMapsWidget`](https://github.com/rithik-dev/google_maps_widget/blob/master/lib/src/main_widget.dart) widget to your widget tree and pass all the required parameters to get started. This widget will create a route between the source and the destination LatLng's provided. 155 | ```dart 156 | import 'package:google_maps_widget/google_maps_widget.dart'; 157 | 158 | GoogleMapsWidget( 159 | apiKey: "YOUR KEY HERE", 160 | sourceLatLng: LatLng(40.484000837597925, -3.369978368282318), 161 | destinationLatLng: LatLng(40.48017307700204, -3.3618026599287987), 162 | ), 163 | ``` 164 | 165 | 3. One can create a controller and interact with the google maps controller, or update the source and destination LatLng's. 166 | ```dart 167 | // can create a controller, and call methods to update source loc, 168 | // destination loc, interact with the google maps controller to 169 | // show/hide markers programmatically etc. 170 | final mapsWidgetController = GlobalKey(); 171 | 172 | // Pass this controller to the "key" param in "GoogleMapsWidget" widget, and then 173 | // call like this to update source or destination, this will also rebuild the route. 174 | mapsWidgetController.currentState!.setSourceLatLng( 175 | LatLng( 176 | 40.484000837597925 * (Random().nextDouble()), 177 | -3.369978368282318, 178 | ), 179 | ); 180 | 181 | // or, can interact with the google maps controller directly to focus on a marker etc.. 182 | 183 | final googleMapsCon = await mapsWidgetController.currentState!.getGoogleMapsController(); 184 | googleMapsCon.showMarkerInfoWindow(MarkerIconInfo.sourceMarkerId); 185 | ``` 186 | 187 | --- 188 | 189 | # 🎯 Sample Usage 190 | 191 | # FIXME 192 | 193 | See the [example](https://github.com/rithik-dev/google_maps_widget/blob/master/example) app for a complete app. Learn how to setup the example app for testing [here](https://github.com/rithik-dev/google_maps_widget/blob/master/example/README.md). 194 | 195 | Check out the full API reference of the widget [here](https://pub.dev/documentation/google_maps_widget/latest/google_maps_widget/GoogleMapsWidget-class.html). 196 | 197 | ```dart 198 | import 'dart:math'; 199 | 200 | import 'package:flutter/material.dart'; 201 | import 'package:google_maps_widget/google_maps_widget.dart'; 202 | 203 | void main() { 204 | runApp(MyApp()); 205 | } 206 | 207 | class MyApp extends StatelessWidget { 208 | // can create a controller, and call methods to update source loc, 209 | // destination loc, interact with the google maps controller to 210 | // show/hide markers programmatically etc. 211 | final mapsWidgetController = GlobalKey(); 212 | 213 | @override 214 | Widget build(BuildContext context) { 215 | return MaterialApp( 216 | home: SafeArea( 217 | child: Scaffold( 218 | body: Column( 219 | children: [ 220 | Expanded( 221 | child: GoogleMapsWidget( 222 | apiKey: "YOUR GOOGLE MAPS API KEY HERE", 223 | key: mapsWidgetController, 224 | sourceLatLng: LatLng( 225 | 40.484000837597925, 226 | -3.369978368282318, 227 | ), 228 | destinationLatLng: LatLng( 229 | 40.48017307700204, 230 | -3.3618026599287987, 231 | ), 232 | 233 | /////////////////////////////////////////////////////// 234 | ////////////// OPTIONAL PARAMETERS ////////////// 235 | /////////////////////////////////////////////////////// 236 | 237 | routeWidth: 2, 238 | sourceMarkerIconInfo: MarkerIconInfo( 239 | infoWindowTitle: "This is source name", 240 | onTapInfoWindow: (_) { 241 | print("Tapped on source info window"); 242 | }, 243 | assetPath: "assets/images/house-marker-icon.png", 244 | ), 245 | destinationMarkerIconInfo: MarkerIconInfo( 246 | assetPath: "assets/images/restaurant-marker-icon.png", 247 | ), 248 | driverMarkerIconInfo: MarkerIconInfo( 249 | infoWindowTitle: "Alex", 250 | assetPath: "assets/images/driver-marker-icon.png", 251 | onTapMarker: (currentLocation) { 252 | print("Driver is currently at $currentLocation"); 253 | }, 254 | assetMarkerSize: Size.square(125), 255 | rotation: 90, 256 | ), 257 | updatePolylinesOnDriverLocUpdate: true, 258 | onPolylineUpdate: (_) { 259 | print("Polyline updated"); 260 | }, 261 | // mock stream 262 | driverCoordinatesStream: Stream.periodic( 263 | Duration(milliseconds: 500), 264 | (i) => LatLng( 265 | 40.47747872288886 + i / 10000, 266 | -3.368043154478073 - i / 10000, 267 | ), 268 | ), 269 | totalTimeCallback: (time) => print(time), 270 | totalDistanceCallback: (distance) => print(distance), 271 | ), 272 | ), 273 | // demonstrates how to interact with the controller 274 | Padding( 275 | padding: const EdgeInsets.all(10), 276 | child: Row( 277 | children: [ 278 | Expanded( 279 | child: ElevatedButton( 280 | onPressed: () { 281 | mapsWidgetController.currentState!.setSourceLatLng( 282 | LatLng( 283 | 40.484000837597925 * (Random().nextDouble()), 284 | -3.369978368282318, 285 | ), 286 | ); 287 | }, 288 | child: Text('Update source'), 289 | ), 290 | ), 291 | const SizedBox(width: 10), 292 | Expanded( 293 | child: ElevatedButton( 294 | onPressed: () async { 295 | final googleMapsCon = await mapsWidgetController 296 | .currentState! 297 | .getGoogleMapsController(); 298 | googleMapsCon.showMarkerInfoWindow( 299 | MarkerIconInfo.sourceMarkerId, 300 | ); 301 | }, 302 | child: Text('Show source info'), 303 | ), 304 | ), 305 | ], 306 | ), 307 | ), 308 | ], 309 | ), 310 | ), 311 | ), 312 | ); 313 | } 314 | } 315 | ``` 316 | 317 | --- 318 | 319 | # 👤 Collaborators 320 | 321 | 322 | | Name | GitHub | Linkedin | 323 | |-----------------------------------|-------------------------------------|-------------------------------------| 324 | | Rithik Bhandari | [github/rithik-dev](https://github.com/rithik-dev) | [linkedin/rithik-bhandari](https://www.linkedin.com/in/rithik-bhandari) | 325 | -------------------------------------------------------------------------------- /analysis_options.yaml: -------------------------------------------------------------------------------- 1 | # This file configures the analyzer, which statically analyzes Dart code to 2 | # check for errors, warnings, and lints. 3 | # 4 | # The issues identified by the analyzer are surfaced in the UI of Dart-enabled 5 | # IDEs (https://dart.dev/tools#ides-and-editors). The analyzer can also be 6 | # invoked from the command line by running `flutter analyze`. 7 | 8 | # The following line activates a set of recommended lints for Flutter apps, 9 | # packages, and plugins designed to encourage good coding practices. 10 | include: package:flutter_lints/flutter.yaml 11 | 12 | linter: 13 | # The lint rules applied to this project can be customized in the 14 | # section below to disable rules from the `package:flutter_lints/flutter.yaml` 15 | # included above or to enable additional rules. A list of all available lints 16 | # and their documentation is published at 17 | # https://dart-lang.github.io/linter/lints/index.html. 18 | # 19 | # Instead of disabling a lint rule for the entire project in the 20 | # section below, it can also be suppressed for a single line of code 21 | # or a specific dart file by using the `// ignore: name_of_lint` and 22 | # `// ignore_for_file: name_of_lint` syntax on the line or in the file 23 | # producing the lint. 24 | rules: 25 | # avoid_print: false # Uncomment to disable the `avoid_print` rule 26 | # prefer_single_quotes: true # Uncomment to enable the `prefer_single_quotes` rule 27 | 28 | # Additional information about this file can be found at 29 | # https://dart.dev/guides/language/analysis-options 30 | -------------------------------------------------------------------------------- /example/.fvmrc: -------------------------------------------------------------------------------- 1 | { 2 | "flutter": "3.24.3" 3 | } -------------------------------------------------------------------------------- /example/.gitignore: -------------------------------------------------------------------------------- 1 | # Miscellaneous 2 | *.class 3 | *.log 4 | *.pyc 5 | *.swp 6 | .DS_Store 7 | .atom/ 8 | .buildlog/ 9 | .history 10 | .svn/ 11 | 12 | # IntelliJ related 13 | *.iml 14 | *.ipr 15 | *.iws 16 | .idea/ 17 | 18 | # The .vscode folder contains launch configuration and tasks you configure in 19 | # VS Code which you may wish to be included in version control, so this line 20 | # is commented out by default. 21 | #.vscode/ 22 | 23 | # Flutter/Dart/Pub related 24 | **/doc/api/ 25 | **/ios/Flutter/.last_build_id 26 | .dart_tool/ 27 | .flutter-plugins 28 | .flutter-plugins-dependencies 29 | .packages 30 | .pub-cache/ 31 | .pub/ 32 | /build/ 33 | 34 | # Web related 35 | lib/generated_plugin_registrant.dart 36 | 37 | # Symbolication related 38 | app.*.symbols 39 | 40 | # Obfuscation related 41 | app.*.map.json 42 | 43 | # Android Studio will place build artifacts here 44 | /android/app/debug 45 | /android/app/profile 46 | /android/app/release 47 | 48 | # FVM Version Cache 49 | .fvm/ -------------------------------------------------------------------------------- /example/.metadata: -------------------------------------------------------------------------------- 1 | # This file tracks properties of this Flutter project. 2 | # Used by Flutter tool to assess capabilities and perform upgrades etc. 3 | # 4 | # This file should be version controlled and should not be manually edited. 5 | 6 | version: 7 | revision: b1395592de68cc8ac4522094ae59956dd21a91db 8 | channel: stable 9 | 10 | project_type: app 11 | -------------------------------------------------------------------------------- /example/README.md: -------------------------------------------------------------------------------- 1 | # google_maps_widget_demo 2 | 3 | A new Flutter application to show the demo for google_maps_widget package. 4 | 5 | ## Getting Started 6 | 7 | This project is a starting point for a Flutter application. 8 | 9 | A few resources to get you started if this is your first Flutter project: 10 | 11 | - [Lab: Write your first Flutter app](https://flutter.dev/docs/get-started/codelab) 12 | - [Cookbook: Useful Flutter samples](https://flutter.dev/docs/cookbook) 13 | 14 | For help getting started with Flutter, view our 15 | [online documentation](https://flutter.dev/docs), which offers tutorials, 16 | samples, guidance on mobile development, and a full API reference. 17 | -------------------------------------------------------------------------------- /example/analysis_options.yaml: -------------------------------------------------------------------------------- 1 | # This file configures the analyzer, which statically analyzes Dart code to 2 | # check for errors, warnings, and lints. 3 | # 4 | # The issues identified by the analyzer are surfaced in the UI of Dart-enabled 5 | # IDEs (https://dart.dev/tools#ides-and-editors). The analyzer can also be 6 | # invoked from the command line by running `flutter analyze`. 7 | 8 | # The following line activates a set of recommended lints for Flutter apps, 9 | # packages, and plugins designed to encourage good coding practices. 10 | include: package:flutter_lints/flutter.yaml 11 | 12 | linter: 13 | # The lint rules applied to this project can be customized in the 14 | # section below to disable rules from the `package:flutter_lints/flutter.yaml` 15 | # included above or to enable additional rules. A list of all available lints 16 | # and their documentation is published at https://dart.dev/lints. 17 | # 18 | # Instead of disabling a lint rule for the entire project in the 19 | # section below, it can also be suppressed for a single line of code 20 | # or a specific dart file by using the `// ignore: name_of_lint` and 21 | # `// ignore_for_file: name_of_lint` syntax on the line or in the file 22 | # producing the lint. 23 | rules: 24 | # avoid_print: false # Uncomment to disable the `avoid_print` rule 25 | # prefer_single_quotes: true # Uncomment to enable the `prefer_single_quotes` rule 26 | 27 | # Additional information about this file can be found at 28 | # https://dart.dev/guides/language/analysis-options 29 | -------------------------------------------------------------------------------- /example/android/.gitignore: -------------------------------------------------------------------------------- 1 | gradle-wrapper.jar 2 | /.gradle 3 | /captures/ 4 | /gradlew 5 | /gradlew.bat 6 | /local.properties 7 | GeneratedPluginRegistrant.java 8 | 9 | # Remember to never publicly share your keystore. 10 | # See https://flutter.dev/to/reference-keystore 11 | key.properties 12 | **/*.keystore 13 | **/*.jks 14 | -------------------------------------------------------------------------------- /example/android/app/build.gradle: -------------------------------------------------------------------------------- 1 | plugins { 2 | id "com.android.application" 3 | id "kotlin-android" 4 | // The Flutter Gradle Plugin must be applied after the Android and Kotlin Gradle plugins. 5 | id "dev.flutter.flutter-gradle-plugin" 6 | } 7 | 8 | android { 9 | namespace = "com.example.google_maps_widget_demo" 10 | compileSdk = 34 11 | ndkVersion = flutter.ndkVersion 12 | 13 | compileOptions { 14 | sourceCompatibility = JavaVersion.VERSION_1_8 15 | targetCompatibility = JavaVersion.VERSION_1_8 16 | } 17 | 18 | kotlinOptions { 19 | jvmTarget = JavaVersion.VERSION_1_8 20 | } 21 | 22 | defaultConfig { 23 | // TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html). 24 | applicationId = "com.example.google_maps_widget_demo" 25 | // You can update the following values to match your application needs. 26 | // For more information, see: https://flutter.dev/to/review-gradle-config. 27 | minSdk = 20 28 | targetSdk = 30 29 | versionCode = flutter.versionCode 30 | versionName = flutter.versionName 31 | } 32 | 33 | buildTypes { 34 | release { 35 | // TODO: Add your own signing config for the release build. 36 | // Signing with the debug keys for now, so `flutter run --release` works. 37 | signingConfig = signingConfigs.debug 38 | } 39 | } 40 | } 41 | 42 | flutter { 43 | source = "../.." 44 | } 45 | -------------------------------------------------------------------------------- /example/android/app/src/debug/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /example/android/app/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 10 | 11 | 20 | 24 | 28 | 29 | 30 | 31 | 32 | 33 | 35 | 38 | 39 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | -------------------------------------------------------------------------------- /example/android/app/src/main/kotlin/com/example/google_maps_widget_demo/MainActivity.kt: -------------------------------------------------------------------------------- 1 | package com.example.google_maps_widget_demo 2 | 3 | import io.flutter.embedding.android.FlutterActivity 4 | 5 | class MainActivity: FlutterActivity() 6 | -------------------------------------------------------------------------------- /example/android/app/src/main/res/drawable-v21/launch_background.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 12 | 13 | -------------------------------------------------------------------------------- /example/android/app/src/main/res/drawable/launch_background.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 12 | 13 | -------------------------------------------------------------------------------- /example/android/app/src/main/res/mipmap-hdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rithik-dev/google_maps_widget/714f8e4ec998db322aa57a08f138140ccbc41f43/example/android/app/src/main/res/mipmap-hdpi/ic_launcher.png -------------------------------------------------------------------------------- /example/android/app/src/main/res/mipmap-mdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rithik-dev/google_maps_widget/714f8e4ec998db322aa57a08f138140ccbc41f43/example/android/app/src/main/res/mipmap-mdpi/ic_launcher.png -------------------------------------------------------------------------------- /example/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rithik-dev/google_maps_widget/714f8e4ec998db322aa57a08f138140ccbc41f43/example/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png -------------------------------------------------------------------------------- /example/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rithik-dev/google_maps_widget/714f8e4ec998db322aa57a08f138140ccbc41f43/example/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /example/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rithik-dev/google_maps_widget/714f8e4ec998db322aa57a08f138140ccbc41f43/example/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /example/android/app/src/main/res/values-night/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 9 | 15 | 18 | 19 | -------------------------------------------------------------------------------- /example/android/app/src/main/res/values/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 9 | 15 | 18 | 19 | -------------------------------------------------------------------------------- /example/android/app/src/profile/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /example/android/build.gradle: -------------------------------------------------------------------------------- 1 | allprojects { 2 | repositories { 3 | google() 4 | mavenCentral() 5 | } 6 | } 7 | 8 | rootProject.buildDir = "../build" 9 | subprojects { 10 | project.buildDir = "${rootProject.buildDir}/${project.name}" 11 | } 12 | subprojects { 13 | project.evaluationDependsOn(":app") 14 | } 15 | 16 | tasks.register("clean", Delete) { 17 | delete rootProject.buildDir 18 | } 19 | -------------------------------------------------------------------------------- /example/android/gradle.properties: -------------------------------------------------------------------------------- 1 | org.gradle.jvmargs=-Xmx4G -XX:MaxMetaspaceSize=2G -XX:+HeapDumpOnOutOfMemoryError 2 | android.useAndroidX=true 3 | android.enableJetifier=true 4 | -------------------------------------------------------------------------------- /example/android/gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionBase=GRADLE_USER_HOME 2 | distributionPath=wrapper/dists 3 | zipStoreBase=GRADLE_USER_HOME 4 | zipStorePath=wrapper/dists 5 | distributionUrl=https\://services.gradle.org/distributions/gradle-8.3-all.zip 6 | -------------------------------------------------------------------------------- /example/android/settings.gradle: -------------------------------------------------------------------------------- 1 | pluginManagement { 2 | def flutterSdkPath = { 3 | def properties = new Properties() 4 | file("local.properties").withInputStream { properties.load(it) } 5 | def flutterSdkPath = properties.getProperty("flutter.sdk") 6 | assert flutterSdkPath != null, "flutter.sdk not set in local.properties" 7 | return flutterSdkPath 8 | }() 9 | 10 | includeBuild("$flutterSdkPath/packages/flutter_tools/gradle") 11 | 12 | repositories { 13 | google() 14 | mavenCentral() 15 | gradlePluginPortal() 16 | } 17 | } 18 | 19 | buildscript { 20 | dependencies { 21 | // Add our classpath 22 | classpath 'com.google.gms:google-services:4.4.1' 23 | // Add More 24 | } 25 | } 26 | 27 | plugins { 28 | id "dev.flutter.flutter-plugin-loader" version "1.0.0" 29 | id "com.android.application" version "8.1.0" apply false 30 | id "org.jetbrains.kotlin.android" version "1.8.22" apply false 31 | } 32 | 33 | include ":app" 34 | -------------------------------------------------------------------------------- /example/assets/images/driver-marker-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rithik-dev/google_maps_widget/714f8e4ec998db322aa57a08f138140ccbc41f43/example/assets/images/driver-marker-icon.png -------------------------------------------------------------------------------- /example/assets/images/house-marker-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rithik-dev/google_maps_widget/714f8e4ec998db322aa57a08f138140ccbc41f43/example/assets/images/house-marker-icon.png -------------------------------------------------------------------------------- /example/assets/images/restaurant-marker-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rithik-dev/google_maps_widget/714f8e4ec998db322aa57a08f138140ccbc41f43/example/assets/images/restaurant-marker-icon.png -------------------------------------------------------------------------------- /example/ios/.gitignore: -------------------------------------------------------------------------------- 1 | **/dgph 2 | *.mode1v3 3 | *.mode2v3 4 | *.moved-aside 5 | *.pbxuser 6 | *.perspectivev3 7 | **/*sync/ 8 | .sconsign.dblite 9 | .tags* 10 | **/.vagrant/ 11 | **/DerivedData/ 12 | Icon? 13 | **/Pods/ 14 | **/.symlinks/ 15 | profile 16 | xcuserdata 17 | **/.generated/ 18 | Flutter/App.framework 19 | Flutter/Flutter.framework 20 | Flutter/Flutter.podspec 21 | Flutter/Generated.xcconfig 22 | Flutter/ephemeral/ 23 | Flutter/app.flx 24 | Flutter/app.zip 25 | Flutter/flutter_assets/ 26 | Flutter/flutter_export_environment.sh 27 | ServiceDefinitions.json 28 | Runner/GeneratedPluginRegistrant.* 29 | 30 | # Exceptions to above rules. 31 | !default.mode1v3 32 | !default.mode2v3 33 | !default.pbxuser 34 | !default.perspectivev3 35 | -------------------------------------------------------------------------------- /example/ios/Flutter/AppFrameworkInfo.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | App 9 | CFBundleIdentifier 10 | io.flutter.flutter.app 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | App 15 | CFBundlePackageType 16 | FMWK 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | 1.0 23 | MinimumOSVersion 24 | 12.0 25 | 26 | 27 | -------------------------------------------------------------------------------- /example/ios/Flutter/Debug.xcconfig: -------------------------------------------------------------------------------- 1 | #include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig" 2 | #include "Generated.xcconfig" 3 | -------------------------------------------------------------------------------- /example/ios/Flutter/Release.xcconfig: -------------------------------------------------------------------------------- 1 | #include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig" 2 | #include "Generated.xcconfig" 3 | -------------------------------------------------------------------------------- /example/ios/Podfile: -------------------------------------------------------------------------------- 1 | # Uncomment this line to define a global platform for your project 2 | # platform :ios, '12.0' 3 | 4 | # CocoaPods analytics sends network stats synchronously affecting flutter build latency. 5 | ENV['COCOAPODS_DISABLE_STATS'] = 'true' 6 | 7 | project 'Runner', { 8 | 'Debug' => :debug, 9 | 'Profile' => :release, 10 | 'Release' => :release, 11 | } 12 | 13 | def flutter_root 14 | generated_xcode_build_settings_path = File.expand_path(File.join('..', 'Flutter', 'Generated.xcconfig'), __FILE__) 15 | unless File.exist?(generated_xcode_build_settings_path) 16 | raise "#{generated_xcode_build_settings_path} must exist. If you're running pod install manually, make sure flutter pub get is executed first" 17 | end 18 | 19 | File.foreach(generated_xcode_build_settings_path) do |line| 20 | matches = line.match(/FLUTTER_ROOT\=(.*)/) 21 | return matches[1].strip if matches 22 | end 23 | raise "FLUTTER_ROOT not found in #{generated_xcode_build_settings_path}. Try deleting Generated.xcconfig, then run flutter pub get" 24 | end 25 | 26 | require File.expand_path(File.join('packages', 'flutter_tools', 'bin', 'podhelper'), flutter_root) 27 | 28 | flutter_ios_podfile_setup 29 | 30 | target 'Runner' do 31 | use_frameworks! 32 | use_modular_headers! 33 | 34 | flutter_install_all_ios_pods File.dirname(File.realpath(__FILE__)) 35 | target 'RunnerTests' do 36 | inherit! :search_paths 37 | end 38 | end 39 | 40 | post_install do |installer| 41 | installer.pods_project.targets.each do |target| 42 | flutter_additional_ios_build_settings(target) 43 | end 44 | end 45 | -------------------------------------------------------------------------------- /example/ios/Runner.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 54; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */ = {isa = PBXBuildFile; fileRef = 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */; }; 11 | 331C808B294A63AB00263BE5 /* RunnerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 331C807B294A618700263BE5 /* RunnerTests.swift */; }; 12 | 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */ = {isa = PBXBuildFile; fileRef = 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */; }; 13 | 74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 74858FAE1ED2DC5600515810 /* AppDelegate.swift */; }; 14 | 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FA1CF9000F007C117D /* Main.storyboard */; }; 15 | 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FD1CF9000F007C117D /* Assets.xcassets */; }; 16 | 97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */; }; 17 | /* End PBXBuildFile section */ 18 | 19 | /* Begin PBXContainerItemProxy section */ 20 | 331C8085294A63A400263BE5 /* PBXContainerItemProxy */ = { 21 | isa = PBXContainerItemProxy; 22 | containerPortal = 97C146E61CF9000F007C117D /* Project object */; 23 | proxyType = 1; 24 | remoteGlobalIDString = 97C146ED1CF9000F007C117D; 25 | remoteInfo = Runner; 26 | }; 27 | /* End PBXContainerItemProxy section */ 28 | 29 | /* Begin PBXCopyFilesBuildPhase section */ 30 | 9705A1C41CF9048500538489 /* Embed Frameworks */ = { 31 | isa = PBXCopyFilesBuildPhase; 32 | buildActionMask = 2147483647; 33 | dstPath = ""; 34 | dstSubfolderSpec = 10; 35 | files = ( 36 | ); 37 | name = "Embed Frameworks"; 38 | runOnlyForDeploymentPostprocessing = 0; 39 | }; 40 | /* End PBXCopyFilesBuildPhase section */ 41 | 42 | /* Begin PBXFileReference section */ 43 | 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GeneratedPluginRegistrant.h; sourceTree = ""; }; 44 | 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GeneratedPluginRegistrant.m; sourceTree = ""; }; 45 | 331C807B294A618700263BE5 /* RunnerTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RunnerTests.swift; sourceTree = ""; }; 46 | 331C8081294A63A400263BE5 /* RunnerTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = RunnerTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; 47 | 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = AppFrameworkInfo.plist; path = Flutter/AppFrameworkInfo.plist; sourceTree = ""; }; 48 | 74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "Runner-Bridging-Header.h"; sourceTree = ""; }; 49 | 74858FAE1ED2DC5600515810 /* AppDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; 50 | 7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = Release.xcconfig; path = Flutter/Release.xcconfig; sourceTree = ""; }; 51 | 9740EEB21CF90195004384FC /* Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Debug.xcconfig; path = Flutter/Debug.xcconfig; sourceTree = ""; }; 52 | 9740EEB31CF90195004384FC /* Generated.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Generated.xcconfig; path = Flutter/Generated.xcconfig; sourceTree = ""; }; 53 | 97C146EE1CF9000F007C117D /* Runner.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Runner.app; sourceTree = BUILT_PRODUCTS_DIR; }; 54 | 97C146FB1CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; 55 | 97C146FD1CF9000F007C117D /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; 56 | 97C147001CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; 57 | 97C147021CF9000F007C117D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 58 | /* End PBXFileReference section */ 59 | 60 | /* Begin PBXFrameworksBuildPhase section */ 61 | 97C146EB1CF9000F007C117D /* Frameworks */ = { 62 | isa = PBXFrameworksBuildPhase; 63 | buildActionMask = 2147483647; 64 | files = ( 65 | ); 66 | runOnlyForDeploymentPostprocessing = 0; 67 | }; 68 | /* End PBXFrameworksBuildPhase section */ 69 | 70 | /* Begin PBXGroup section */ 71 | 331C8082294A63A400263BE5 /* RunnerTests */ = { 72 | isa = PBXGroup; 73 | children = ( 74 | 331C807B294A618700263BE5 /* RunnerTests.swift */, 75 | ); 76 | path = RunnerTests; 77 | sourceTree = ""; 78 | }; 79 | 9740EEB11CF90186004384FC /* Flutter */ = { 80 | isa = PBXGroup; 81 | children = ( 82 | 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */, 83 | 9740EEB21CF90195004384FC /* Debug.xcconfig */, 84 | 7AFA3C8E1D35360C0083082E /* Release.xcconfig */, 85 | 9740EEB31CF90195004384FC /* Generated.xcconfig */, 86 | ); 87 | name = Flutter; 88 | sourceTree = ""; 89 | }; 90 | 97C146E51CF9000F007C117D = { 91 | isa = PBXGroup; 92 | children = ( 93 | 9740EEB11CF90186004384FC /* Flutter */, 94 | 97C146F01CF9000F007C117D /* Runner */, 95 | 97C146EF1CF9000F007C117D /* Products */, 96 | 331C8082294A63A400263BE5 /* RunnerTests */, 97 | ); 98 | sourceTree = ""; 99 | }; 100 | 97C146EF1CF9000F007C117D /* Products */ = { 101 | isa = PBXGroup; 102 | children = ( 103 | 97C146EE1CF9000F007C117D /* Runner.app */, 104 | 331C8081294A63A400263BE5 /* RunnerTests.xctest */, 105 | ); 106 | name = Products; 107 | sourceTree = ""; 108 | }; 109 | 97C146F01CF9000F007C117D /* Runner */ = { 110 | isa = PBXGroup; 111 | children = ( 112 | 97C146FA1CF9000F007C117D /* Main.storyboard */, 113 | 97C146FD1CF9000F007C117D /* Assets.xcassets */, 114 | 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */, 115 | 97C147021CF9000F007C117D /* Info.plist */, 116 | 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */, 117 | 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */, 118 | 74858FAE1ED2DC5600515810 /* AppDelegate.swift */, 119 | 74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */, 120 | ); 121 | path = Runner; 122 | sourceTree = ""; 123 | }; 124 | /* End PBXGroup section */ 125 | 126 | /* Begin PBXNativeTarget section */ 127 | 331C8080294A63A400263BE5 /* RunnerTests */ = { 128 | isa = PBXNativeTarget; 129 | buildConfigurationList = 331C8087294A63A400263BE5 /* Build configuration list for PBXNativeTarget "RunnerTests" */; 130 | buildPhases = ( 131 | 331C807D294A63A400263BE5 /* Sources */, 132 | 331C807F294A63A400263BE5 /* Resources */, 133 | ); 134 | buildRules = ( 135 | ); 136 | dependencies = ( 137 | 331C8086294A63A400263BE5 /* PBXTargetDependency */, 138 | ); 139 | name = RunnerTests; 140 | productName = RunnerTests; 141 | productReference = 331C8081294A63A400263BE5 /* RunnerTests.xctest */; 142 | productType = "com.apple.product-type.bundle.unit-test"; 143 | }; 144 | 97C146ED1CF9000F007C117D /* Runner */ = { 145 | isa = PBXNativeTarget; 146 | buildConfigurationList = 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */; 147 | buildPhases = ( 148 | 9740EEB61CF901F6004384FC /* Run Script */, 149 | 97C146EA1CF9000F007C117D /* Sources */, 150 | 97C146EB1CF9000F007C117D /* Frameworks */, 151 | 97C146EC1CF9000F007C117D /* Resources */, 152 | 9705A1C41CF9048500538489 /* Embed Frameworks */, 153 | 3B06AD1E1E4923F5004D2608 /* Thin Binary */, 154 | ); 155 | buildRules = ( 156 | ); 157 | dependencies = ( 158 | ); 159 | name = Runner; 160 | productName = Runner; 161 | productReference = 97C146EE1CF9000F007C117D /* Runner.app */; 162 | productType = "com.apple.product-type.application"; 163 | }; 164 | /* End PBXNativeTarget section */ 165 | 166 | /* Begin PBXProject section */ 167 | 97C146E61CF9000F007C117D /* Project object */ = { 168 | isa = PBXProject; 169 | attributes = { 170 | BuildIndependentTargetsInParallel = YES; 171 | LastUpgradeCheck = 1510; 172 | ORGANIZATIONNAME = ""; 173 | TargetAttributes = { 174 | 331C8080294A63A400263BE5 = { 175 | CreatedOnToolsVersion = 14.0; 176 | TestTargetID = 97C146ED1CF9000F007C117D; 177 | }; 178 | 97C146ED1CF9000F007C117D = { 179 | CreatedOnToolsVersion = 7.3.1; 180 | LastSwiftMigration = 1100; 181 | }; 182 | }; 183 | }; 184 | buildConfigurationList = 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */; 185 | compatibilityVersion = "Xcode 9.3"; 186 | developmentRegion = en; 187 | hasScannedForEncodings = 0; 188 | knownRegions = ( 189 | en, 190 | Base, 191 | ); 192 | mainGroup = 97C146E51CF9000F007C117D; 193 | productRefGroup = 97C146EF1CF9000F007C117D /* Products */; 194 | projectDirPath = ""; 195 | projectRoot = ""; 196 | targets = ( 197 | 97C146ED1CF9000F007C117D /* Runner */, 198 | 331C8080294A63A400263BE5 /* RunnerTests */, 199 | ); 200 | }; 201 | /* End PBXProject section */ 202 | 203 | /* Begin PBXResourcesBuildPhase section */ 204 | 331C807F294A63A400263BE5 /* Resources */ = { 205 | isa = PBXResourcesBuildPhase; 206 | buildActionMask = 2147483647; 207 | files = ( 208 | ); 209 | runOnlyForDeploymentPostprocessing = 0; 210 | }; 211 | 97C146EC1CF9000F007C117D /* Resources */ = { 212 | isa = PBXResourcesBuildPhase; 213 | buildActionMask = 2147483647; 214 | files = ( 215 | 97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */, 216 | 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */, 217 | 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */, 218 | 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */, 219 | ); 220 | runOnlyForDeploymentPostprocessing = 0; 221 | }; 222 | /* End PBXResourcesBuildPhase section */ 223 | 224 | /* Begin PBXShellScriptBuildPhase section */ 225 | 3B06AD1E1E4923F5004D2608 /* Thin Binary */ = { 226 | isa = PBXShellScriptBuildPhase; 227 | alwaysOutOfDate = 1; 228 | buildActionMask = 2147483647; 229 | files = ( 230 | ); 231 | inputPaths = ( 232 | "${TARGET_BUILD_DIR}/${INFOPLIST_PATH}", 233 | ); 234 | name = "Thin Binary"; 235 | outputPaths = ( 236 | ); 237 | runOnlyForDeploymentPostprocessing = 0; 238 | shellPath = /bin/sh; 239 | shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" embed_and_thin"; 240 | }; 241 | 9740EEB61CF901F6004384FC /* Run Script */ = { 242 | isa = PBXShellScriptBuildPhase; 243 | alwaysOutOfDate = 1; 244 | buildActionMask = 2147483647; 245 | files = ( 246 | ); 247 | inputPaths = ( 248 | ); 249 | name = "Run Script"; 250 | outputPaths = ( 251 | ); 252 | runOnlyForDeploymentPostprocessing = 0; 253 | shellPath = /bin/sh; 254 | shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" build"; 255 | }; 256 | /* End PBXShellScriptBuildPhase section */ 257 | 258 | /* Begin PBXSourcesBuildPhase section */ 259 | 331C807D294A63A400263BE5 /* Sources */ = { 260 | isa = PBXSourcesBuildPhase; 261 | buildActionMask = 2147483647; 262 | files = ( 263 | 331C808B294A63AB00263BE5 /* RunnerTests.swift in Sources */, 264 | ); 265 | runOnlyForDeploymentPostprocessing = 0; 266 | }; 267 | 97C146EA1CF9000F007C117D /* Sources */ = { 268 | isa = PBXSourcesBuildPhase; 269 | buildActionMask = 2147483647; 270 | files = ( 271 | 74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */, 272 | 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */, 273 | ); 274 | runOnlyForDeploymentPostprocessing = 0; 275 | }; 276 | /* End PBXSourcesBuildPhase section */ 277 | 278 | /* Begin PBXTargetDependency section */ 279 | 331C8086294A63A400263BE5 /* PBXTargetDependency */ = { 280 | isa = PBXTargetDependency; 281 | target = 97C146ED1CF9000F007C117D /* Runner */; 282 | targetProxy = 331C8085294A63A400263BE5 /* PBXContainerItemProxy */; 283 | }; 284 | /* End PBXTargetDependency section */ 285 | 286 | /* Begin PBXVariantGroup section */ 287 | 97C146FA1CF9000F007C117D /* Main.storyboard */ = { 288 | isa = PBXVariantGroup; 289 | children = ( 290 | 97C146FB1CF9000F007C117D /* Base */, 291 | ); 292 | name = Main.storyboard; 293 | sourceTree = ""; 294 | }; 295 | 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */ = { 296 | isa = PBXVariantGroup; 297 | children = ( 298 | 97C147001CF9000F007C117D /* Base */, 299 | ); 300 | name = LaunchScreen.storyboard; 301 | sourceTree = ""; 302 | }; 303 | /* End PBXVariantGroup section */ 304 | 305 | /* Begin XCBuildConfiguration section */ 306 | 249021D3217E4FDB00AE95B9 /* Profile */ = { 307 | isa = XCBuildConfiguration; 308 | buildSettings = { 309 | ALWAYS_SEARCH_USER_PATHS = NO; 310 | ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES; 311 | CLANG_ANALYZER_NONNULL = YES; 312 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 313 | CLANG_CXX_LIBRARY = "libc++"; 314 | CLANG_ENABLE_MODULES = YES; 315 | CLANG_ENABLE_OBJC_ARC = YES; 316 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 317 | CLANG_WARN_BOOL_CONVERSION = YES; 318 | CLANG_WARN_COMMA = YES; 319 | CLANG_WARN_CONSTANT_CONVERSION = YES; 320 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 321 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 322 | CLANG_WARN_EMPTY_BODY = YES; 323 | CLANG_WARN_ENUM_CONVERSION = YES; 324 | CLANG_WARN_INFINITE_RECURSION = YES; 325 | CLANG_WARN_INT_CONVERSION = YES; 326 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 327 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 328 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 329 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 330 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 331 | CLANG_WARN_STRICT_PROTOTYPES = YES; 332 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 333 | CLANG_WARN_UNREACHABLE_CODE = YES; 334 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 335 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 336 | COPY_PHASE_STRIP = NO; 337 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 338 | ENABLE_NS_ASSERTIONS = NO; 339 | ENABLE_STRICT_OBJC_MSGSEND = YES; 340 | ENABLE_USER_SCRIPT_SANDBOXING = NO; 341 | GCC_C_LANGUAGE_STANDARD = gnu99; 342 | GCC_NO_COMMON_BLOCKS = YES; 343 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 344 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 345 | GCC_WARN_UNDECLARED_SELECTOR = YES; 346 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 347 | GCC_WARN_UNUSED_FUNCTION = YES; 348 | GCC_WARN_UNUSED_VARIABLE = YES; 349 | IPHONEOS_DEPLOYMENT_TARGET = 12.0; 350 | MTL_ENABLE_DEBUG_INFO = NO; 351 | SDKROOT = iphoneos; 352 | SUPPORTED_PLATFORMS = iphoneos; 353 | TARGETED_DEVICE_FAMILY = "1,2"; 354 | VALIDATE_PRODUCT = YES; 355 | }; 356 | name = Profile; 357 | }; 358 | 249021D4217E4FDB00AE95B9 /* Profile */ = { 359 | isa = XCBuildConfiguration; 360 | baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; 361 | buildSettings = { 362 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 363 | CLANG_ENABLE_MODULES = YES; 364 | CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; 365 | DEVELOPMENT_TEAM = KFVRB3N543; 366 | ENABLE_BITCODE = NO; 367 | INFOPLIST_FILE = Runner/Info.plist; 368 | LD_RUNPATH_SEARCH_PATHS = ( 369 | "$(inherited)", 370 | "@executable_path/Frameworks", 371 | ); 372 | PRODUCT_BUNDLE_IDENTIFIER = com.example.googleMapsWidgetDemo; 373 | PRODUCT_NAME = "$(TARGET_NAME)"; 374 | SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; 375 | SWIFT_VERSION = 5.0; 376 | VERSIONING_SYSTEM = "apple-generic"; 377 | }; 378 | name = Profile; 379 | }; 380 | 331C8088294A63A400263BE5 /* Debug */ = { 381 | isa = XCBuildConfiguration; 382 | buildSettings = { 383 | BUNDLE_LOADER = "$(TEST_HOST)"; 384 | CODE_SIGN_STYLE = Automatic; 385 | CURRENT_PROJECT_VERSION = 1; 386 | GENERATE_INFOPLIST_FILE = YES; 387 | MARKETING_VERSION = 1.0; 388 | PRODUCT_BUNDLE_IDENTIFIER = com.example.googleMapsWidgetDemo.RunnerTests; 389 | PRODUCT_NAME = "$(TARGET_NAME)"; 390 | SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; 391 | SWIFT_OPTIMIZATION_LEVEL = "-Onone"; 392 | SWIFT_VERSION = 5.0; 393 | TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Runner.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/Runner"; 394 | }; 395 | name = Debug; 396 | }; 397 | 331C8089294A63A400263BE5 /* Release */ = { 398 | isa = XCBuildConfiguration; 399 | buildSettings = { 400 | BUNDLE_LOADER = "$(TEST_HOST)"; 401 | CODE_SIGN_STYLE = Automatic; 402 | CURRENT_PROJECT_VERSION = 1; 403 | GENERATE_INFOPLIST_FILE = YES; 404 | MARKETING_VERSION = 1.0; 405 | PRODUCT_BUNDLE_IDENTIFIER = com.example.googleMapsWidgetDemo.RunnerTests; 406 | PRODUCT_NAME = "$(TARGET_NAME)"; 407 | SWIFT_VERSION = 5.0; 408 | TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Runner.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/Runner"; 409 | }; 410 | name = Release; 411 | }; 412 | 331C808A294A63A400263BE5 /* Profile */ = { 413 | isa = XCBuildConfiguration; 414 | buildSettings = { 415 | BUNDLE_LOADER = "$(TEST_HOST)"; 416 | CODE_SIGN_STYLE = Automatic; 417 | CURRENT_PROJECT_VERSION = 1; 418 | GENERATE_INFOPLIST_FILE = YES; 419 | MARKETING_VERSION = 1.0; 420 | PRODUCT_BUNDLE_IDENTIFIER = com.example.googleMapsWidgetDemo.RunnerTests; 421 | PRODUCT_NAME = "$(TARGET_NAME)"; 422 | SWIFT_VERSION = 5.0; 423 | TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Runner.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/Runner"; 424 | }; 425 | name = Profile; 426 | }; 427 | 97C147031CF9000F007C117D /* Debug */ = { 428 | isa = XCBuildConfiguration; 429 | buildSettings = { 430 | ALWAYS_SEARCH_USER_PATHS = NO; 431 | ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES; 432 | CLANG_ANALYZER_NONNULL = YES; 433 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 434 | CLANG_CXX_LIBRARY = "libc++"; 435 | CLANG_ENABLE_MODULES = YES; 436 | CLANG_ENABLE_OBJC_ARC = YES; 437 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 438 | CLANG_WARN_BOOL_CONVERSION = YES; 439 | CLANG_WARN_COMMA = YES; 440 | CLANG_WARN_CONSTANT_CONVERSION = YES; 441 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 442 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 443 | CLANG_WARN_EMPTY_BODY = YES; 444 | CLANG_WARN_ENUM_CONVERSION = YES; 445 | CLANG_WARN_INFINITE_RECURSION = YES; 446 | CLANG_WARN_INT_CONVERSION = YES; 447 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 448 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 449 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 450 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 451 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 452 | CLANG_WARN_STRICT_PROTOTYPES = YES; 453 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 454 | CLANG_WARN_UNREACHABLE_CODE = YES; 455 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 456 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 457 | COPY_PHASE_STRIP = NO; 458 | DEBUG_INFORMATION_FORMAT = dwarf; 459 | ENABLE_STRICT_OBJC_MSGSEND = YES; 460 | ENABLE_TESTABILITY = YES; 461 | ENABLE_USER_SCRIPT_SANDBOXING = NO; 462 | GCC_C_LANGUAGE_STANDARD = gnu99; 463 | GCC_DYNAMIC_NO_PIC = NO; 464 | GCC_NO_COMMON_BLOCKS = YES; 465 | GCC_OPTIMIZATION_LEVEL = 0; 466 | GCC_PREPROCESSOR_DEFINITIONS = ( 467 | "DEBUG=1", 468 | "$(inherited)", 469 | ); 470 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 471 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 472 | GCC_WARN_UNDECLARED_SELECTOR = YES; 473 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 474 | GCC_WARN_UNUSED_FUNCTION = YES; 475 | GCC_WARN_UNUSED_VARIABLE = YES; 476 | IPHONEOS_DEPLOYMENT_TARGET = 12.0; 477 | MTL_ENABLE_DEBUG_INFO = YES; 478 | ONLY_ACTIVE_ARCH = YES; 479 | SDKROOT = iphoneos; 480 | TARGETED_DEVICE_FAMILY = "1,2"; 481 | }; 482 | name = Debug; 483 | }; 484 | 97C147041CF9000F007C117D /* Release */ = { 485 | isa = XCBuildConfiguration; 486 | buildSettings = { 487 | ALWAYS_SEARCH_USER_PATHS = NO; 488 | ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES; 489 | CLANG_ANALYZER_NONNULL = YES; 490 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 491 | CLANG_CXX_LIBRARY = "libc++"; 492 | CLANG_ENABLE_MODULES = YES; 493 | CLANG_ENABLE_OBJC_ARC = YES; 494 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 495 | CLANG_WARN_BOOL_CONVERSION = YES; 496 | CLANG_WARN_COMMA = YES; 497 | CLANG_WARN_CONSTANT_CONVERSION = YES; 498 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 499 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 500 | CLANG_WARN_EMPTY_BODY = YES; 501 | CLANG_WARN_ENUM_CONVERSION = YES; 502 | CLANG_WARN_INFINITE_RECURSION = YES; 503 | CLANG_WARN_INT_CONVERSION = YES; 504 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 505 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 506 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 507 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 508 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 509 | CLANG_WARN_STRICT_PROTOTYPES = YES; 510 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 511 | CLANG_WARN_UNREACHABLE_CODE = YES; 512 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 513 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 514 | COPY_PHASE_STRIP = NO; 515 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 516 | ENABLE_NS_ASSERTIONS = NO; 517 | ENABLE_STRICT_OBJC_MSGSEND = YES; 518 | ENABLE_USER_SCRIPT_SANDBOXING = NO; 519 | GCC_C_LANGUAGE_STANDARD = gnu99; 520 | GCC_NO_COMMON_BLOCKS = YES; 521 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 522 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 523 | GCC_WARN_UNDECLARED_SELECTOR = YES; 524 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 525 | GCC_WARN_UNUSED_FUNCTION = YES; 526 | GCC_WARN_UNUSED_VARIABLE = YES; 527 | IPHONEOS_DEPLOYMENT_TARGET = 12.0; 528 | MTL_ENABLE_DEBUG_INFO = NO; 529 | SDKROOT = iphoneos; 530 | SUPPORTED_PLATFORMS = iphoneos; 531 | SWIFT_COMPILATION_MODE = wholemodule; 532 | SWIFT_OPTIMIZATION_LEVEL = "-O"; 533 | TARGETED_DEVICE_FAMILY = "1,2"; 534 | VALIDATE_PRODUCT = YES; 535 | }; 536 | name = Release; 537 | }; 538 | 97C147061CF9000F007C117D /* Debug */ = { 539 | isa = XCBuildConfiguration; 540 | baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */; 541 | buildSettings = { 542 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 543 | CLANG_ENABLE_MODULES = YES; 544 | CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; 545 | DEVELOPMENT_TEAM = KFVRB3N543; 546 | ENABLE_BITCODE = NO; 547 | INFOPLIST_FILE = Runner/Info.plist; 548 | LD_RUNPATH_SEARCH_PATHS = ( 549 | "$(inherited)", 550 | "@executable_path/Frameworks", 551 | ); 552 | PRODUCT_BUNDLE_IDENTIFIER = com.example.googleMapsWidgetDemo; 553 | PRODUCT_NAME = "$(TARGET_NAME)"; 554 | SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; 555 | SWIFT_OPTIMIZATION_LEVEL = "-Onone"; 556 | SWIFT_VERSION = 5.0; 557 | VERSIONING_SYSTEM = "apple-generic"; 558 | }; 559 | name = Debug; 560 | }; 561 | 97C147071CF9000F007C117D /* Release */ = { 562 | isa = XCBuildConfiguration; 563 | baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; 564 | buildSettings = { 565 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 566 | CLANG_ENABLE_MODULES = YES; 567 | CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; 568 | DEVELOPMENT_TEAM = KFVRB3N543; 569 | ENABLE_BITCODE = NO; 570 | INFOPLIST_FILE = Runner/Info.plist; 571 | LD_RUNPATH_SEARCH_PATHS = ( 572 | "$(inherited)", 573 | "@executable_path/Frameworks", 574 | ); 575 | PRODUCT_BUNDLE_IDENTIFIER = com.example.googleMapsWidgetDemo; 576 | PRODUCT_NAME = "$(TARGET_NAME)"; 577 | SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; 578 | SWIFT_VERSION = 5.0; 579 | VERSIONING_SYSTEM = "apple-generic"; 580 | }; 581 | name = Release; 582 | }; 583 | /* End XCBuildConfiguration section */ 584 | 585 | /* Begin XCConfigurationList section */ 586 | 331C8087294A63A400263BE5 /* Build configuration list for PBXNativeTarget "RunnerTests" */ = { 587 | isa = XCConfigurationList; 588 | buildConfigurations = ( 589 | 331C8088294A63A400263BE5 /* Debug */, 590 | 331C8089294A63A400263BE5 /* Release */, 591 | 331C808A294A63A400263BE5 /* Profile */, 592 | ); 593 | defaultConfigurationIsVisible = 0; 594 | defaultConfigurationName = Release; 595 | }; 596 | 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */ = { 597 | isa = XCConfigurationList; 598 | buildConfigurations = ( 599 | 97C147031CF9000F007C117D /* Debug */, 600 | 97C147041CF9000F007C117D /* Release */, 601 | 249021D3217E4FDB00AE95B9 /* Profile */, 602 | ); 603 | defaultConfigurationIsVisible = 0; 604 | defaultConfigurationName = Release; 605 | }; 606 | 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */ = { 607 | isa = XCConfigurationList; 608 | buildConfigurations = ( 609 | 97C147061CF9000F007C117D /* Debug */, 610 | 97C147071CF9000F007C117D /* Release */, 611 | 249021D4217E4FDB00AE95B9 /* Profile */, 612 | ); 613 | defaultConfigurationIsVisible = 0; 614 | defaultConfigurationName = Release; 615 | }; 616 | /* End XCConfigurationList section */ 617 | }; 618 | rootObject = 97C146E61CF9000F007C117D /* Project object */; 619 | } 620 | -------------------------------------------------------------------------------- /example/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /example/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /example/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | PreviewsEnabled 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 37 | 38 | 39 | 40 | 43 | 49 | 50 | 51 | 52 | 53 | 63 | 65 | 71 | 72 | 73 | 74 | 80 | 82 | 88 | 89 | 90 | 91 | 93 | 94 | 97 | 98 | 99 | -------------------------------------------------------------------------------- /example/ios/Runner.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /example/ios/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /example/ios/Runner.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | PreviewsEnabled 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /example/ios/Runner/AppDelegate.m: -------------------------------------------------------------------------------- 1 | #import "AppDelegate.h" 2 | #import "GeneratedPluginRegistrant.h" 3 | #import "GoogleMaps/GoogleMaps.h" 4 | 5 | @implementation AppDelegate 6 | 7 | - (BOOL)application:(UIApplication *)application 8 | didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { 9 | [GMSServices provideAPIKey:@"YOUR KEY HERE"]; 10 | [GeneratedPluginRegistrant registerWithRegistry:self]; 11 | // Override point for customization after application launch. 12 | return [super application:application didFinishLaunchingWithOptions:launchOptions]; 13 | } 14 | 15 | @end 16 | -------------------------------------------------------------------------------- /example/ios/Runner/AppDelegate.swift: -------------------------------------------------------------------------------- 1 | import Flutter 2 | import UIKit 3 | 4 | @main 5 | @objc class AppDelegate: FlutterAppDelegate { 6 | override func application( 7 | _ application: UIApplication, 8 | didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]? 9 | ) -> Bool { 10 | GeneratedPluginRegistrant.register(with: self) 11 | return super.application(application, didFinishLaunchingWithOptions: launchOptions) 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "size" : "20x20", 5 | "idiom" : "iphone", 6 | "filename" : "Icon-App-20x20@2x.png", 7 | "scale" : "2x" 8 | }, 9 | { 10 | "size" : "20x20", 11 | "idiom" : "iphone", 12 | "filename" : "Icon-App-20x20@3x.png", 13 | "scale" : "3x" 14 | }, 15 | { 16 | "size" : "29x29", 17 | "idiom" : "iphone", 18 | "filename" : "Icon-App-29x29@1x.png", 19 | "scale" : "1x" 20 | }, 21 | { 22 | "size" : "29x29", 23 | "idiom" : "iphone", 24 | "filename" : "Icon-App-29x29@2x.png", 25 | "scale" : "2x" 26 | }, 27 | { 28 | "size" : "29x29", 29 | "idiom" : "iphone", 30 | "filename" : "Icon-App-29x29@3x.png", 31 | "scale" : "3x" 32 | }, 33 | { 34 | "size" : "40x40", 35 | "idiom" : "iphone", 36 | "filename" : "Icon-App-40x40@2x.png", 37 | "scale" : "2x" 38 | }, 39 | { 40 | "size" : "40x40", 41 | "idiom" : "iphone", 42 | "filename" : "Icon-App-40x40@3x.png", 43 | "scale" : "3x" 44 | }, 45 | { 46 | "size" : "60x60", 47 | "idiom" : "iphone", 48 | "filename" : "Icon-App-60x60@2x.png", 49 | "scale" : "2x" 50 | }, 51 | { 52 | "size" : "60x60", 53 | "idiom" : "iphone", 54 | "filename" : "Icon-App-60x60@3x.png", 55 | "scale" : "3x" 56 | }, 57 | { 58 | "size" : "20x20", 59 | "idiom" : "ipad", 60 | "filename" : "Icon-App-20x20@1x.png", 61 | "scale" : "1x" 62 | }, 63 | { 64 | "size" : "20x20", 65 | "idiom" : "ipad", 66 | "filename" : "Icon-App-20x20@2x.png", 67 | "scale" : "2x" 68 | }, 69 | { 70 | "size" : "29x29", 71 | "idiom" : "ipad", 72 | "filename" : "Icon-App-29x29@1x.png", 73 | "scale" : "1x" 74 | }, 75 | { 76 | "size" : "29x29", 77 | "idiom" : "ipad", 78 | "filename" : "Icon-App-29x29@2x.png", 79 | "scale" : "2x" 80 | }, 81 | { 82 | "size" : "40x40", 83 | "idiom" : "ipad", 84 | "filename" : "Icon-App-40x40@1x.png", 85 | "scale" : "1x" 86 | }, 87 | { 88 | "size" : "40x40", 89 | "idiom" : "ipad", 90 | "filename" : "Icon-App-40x40@2x.png", 91 | "scale" : "2x" 92 | }, 93 | { 94 | "size" : "76x76", 95 | "idiom" : "ipad", 96 | "filename" : "Icon-App-76x76@1x.png", 97 | "scale" : "1x" 98 | }, 99 | { 100 | "size" : "76x76", 101 | "idiom" : "ipad", 102 | "filename" : "Icon-App-76x76@2x.png", 103 | "scale" : "2x" 104 | }, 105 | { 106 | "size" : "83.5x83.5", 107 | "idiom" : "ipad", 108 | "filename" : "Icon-App-83.5x83.5@2x.png", 109 | "scale" : "2x" 110 | }, 111 | { 112 | "size" : "1024x1024", 113 | "idiom" : "ios-marketing", 114 | "filename" : "Icon-App-1024x1024@1x.png", 115 | "scale" : "1x" 116 | } 117 | ], 118 | "info" : { 119 | "version" : 1, 120 | "author" : "xcode" 121 | } 122 | } 123 | -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rithik-dev/google_maps_widget/714f8e4ec998db322aa57a08f138140ccbc41f43/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rithik-dev/google_maps_widget/714f8e4ec998db322aa57a08f138140ccbc41f43/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rithik-dev/google_maps_widget/714f8e4ec998db322aa57a08f138140ccbc41f43/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rithik-dev/google_maps_widget/714f8e4ec998db322aa57a08f138140ccbc41f43/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rithik-dev/google_maps_widget/714f8e4ec998db322aa57a08f138140ccbc41f43/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rithik-dev/google_maps_widget/714f8e4ec998db322aa57a08f138140ccbc41f43/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rithik-dev/google_maps_widget/714f8e4ec998db322aa57a08f138140ccbc41f43/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rithik-dev/google_maps_widget/714f8e4ec998db322aa57a08f138140ccbc41f43/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rithik-dev/google_maps_widget/714f8e4ec998db322aa57a08f138140ccbc41f43/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rithik-dev/google_maps_widget/714f8e4ec998db322aa57a08f138140ccbc41f43/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rithik-dev/google_maps_widget/714f8e4ec998db322aa57a08f138140ccbc41f43/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rithik-dev/google_maps_widget/714f8e4ec998db322aa57a08f138140ccbc41f43/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rithik-dev/google_maps_widget/714f8e4ec998db322aa57a08f138140ccbc41f43/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rithik-dev/google_maps_widget/714f8e4ec998db322aa57a08f138140ccbc41f43/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rithik-dev/google_maps_widget/714f8e4ec998db322aa57a08f138140ccbc41f43/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "LaunchImage.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "filename" : "LaunchImage@2x.png", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "universal", 15 | "filename" : "LaunchImage@3x.png", 16 | "scale" : "3x" 17 | } 18 | ], 19 | "info" : { 20 | "version" : 1, 21 | "author" : "xcode" 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rithik-dev/google_maps_widget/714f8e4ec998db322aa57a08f138140ccbc41f43/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rithik-dev/google_maps_widget/714f8e4ec998db322aa57a08f138140ccbc41f43/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rithik-dev/google_maps_widget/714f8e4ec998db322aa57a08f138140ccbc41f43/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md: -------------------------------------------------------------------------------- 1 | # Launch Screen Assets 2 | 3 | You can customize the launch screen with your own desired assets by replacing the image files in this directory. 4 | 5 | You can also do it by opening your Flutter project's Xcode project with `open ios/Runner.xcworkspace`, selecting `Runner/Assets.xcassets` in the Project Navigator and dropping in the desired images. -------------------------------------------------------------------------------- /example/ios/Runner/Base.lproj/LaunchScreen.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | -------------------------------------------------------------------------------- /example/ios/Runner/Base.lproj/Main.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /example/ios/Runner/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleDisplayName 8 | GoogleMapsWidget Demo 9 | CFBundleExecutable 10 | $(EXECUTABLE_NAME) 11 | CFBundleIdentifier 12 | $(PRODUCT_BUNDLE_IDENTIFIER) 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundleName 16 | google_maps_widget_demo 17 | CFBundlePackageType 18 | APPL 19 | CFBundleShortVersionString 20 | $(FLUTTER_BUILD_NAME) 21 | CFBundleSignature 22 | ???? 23 | CFBundleVersion 24 | $(FLUTTER_BUILD_NUMBER) 25 | LSRequiresIPhoneOS 26 | 27 | UILaunchStoryboardName 28 | LaunchScreen 29 | UIMainStoryboardFile 30 | Main 31 | UISupportedInterfaceOrientations 32 | 33 | UIInterfaceOrientationPortrait 34 | UIInterfaceOrientationLandscapeLeft 35 | UIInterfaceOrientationLandscapeRight 36 | 37 | UISupportedInterfaceOrientations~ipad 38 | 39 | UIInterfaceOrientationPortrait 40 | UIInterfaceOrientationPortraitUpsideDown 41 | UIInterfaceOrientationLandscapeLeft 42 | UIInterfaceOrientationLandscapeRight 43 | 44 | CADisableMinimumFrameDurationOnPhone 45 | 46 | UIApplicationSupportsIndirectInputEvents 47 | 48 | 49 | 50 | -------------------------------------------------------------------------------- /example/ios/Runner/Runner-Bridging-Header.h: -------------------------------------------------------------------------------- 1 | #import "GeneratedPluginRegistrant.h" 2 | -------------------------------------------------------------------------------- /example/ios/RunnerTests/RunnerTests.swift: -------------------------------------------------------------------------------- 1 | import Flutter 2 | import UIKit 3 | import XCTest 4 | 5 | class RunnerTests: XCTestCase { 6 | 7 | func testExample() { 8 | // If you add code to the Runner application, consider adding tests here. 9 | // See https://developer.apple.com/documentation/xctest for more information about using XCTest. 10 | } 11 | 12 | } 13 | -------------------------------------------------------------------------------- /example/lib/main.dart: -------------------------------------------------------------------------------- 1 | import 'dart:math'; 2 | 3 | import 'package:flutter/material.dart'; 4 | import 'package:google_maps_widget/google_maps_widget.dart'; 5 | 6 | void main() { 7 | runApp(MyApp()); 8 | } 9 | 10 | class MyApp extends StatelessWidget { 11 | MyApp({super.key}); 12 | 13 | // can create a controller, and call methods to update source loc, 14 | // destination loc, interact with the google maps controller to 15 | // show/hide markers programmatically etc. 16 | final mapsWidgetController = GlobalKey(); 17 | 18 | @override 19 | Widget build(BuildContext context) { 20 | return MaterialApp( 21 | home: SafeArea( 22 | child: Scaffold( 23 | body: Column( 24 | children: [ 25 | Expanded( 26 | child: GoogleMapsWidget( 27 | apiKey: "YOUR GOOGLE MAPS API KEY HERE", 28 | key: mapsWidgetController, 29 | sourceLatLng: LatLng( 30 | 40.484000837597925, 31 | -3.369978368282318, 32 | ), 33 | destinationLatLng: LatLng( 34 | 40.48017307700204, 35 | -3.3618026599287987, 36 | ), 37 | 38 | /////////////////////////////////////////////////////// 39 | ////////////// OPTIONAL PARAMETERS ////////////// 40 | /////////////////////////////////////////////////////// 41 | 42 | routeWidth: 2, 43 | sourceMarkerIconInfo: MarkerIconInfo( 44 | infoWindowTitle: "This is source name", 45 | onTapInfoWindow: (_) { 46 | debugPrint("Tapped on source info window"); 47 | }, 48 | assetPath: "assets/images/house-marker-icon.png", 49 | assetMarkerSize: Size.square(50), 50 | ), 51 | destinationMarkerIconInfo: MarkerIconInfo( 52 | assetPath: "assets/images/restaurant-marker-icon.png", 53 | assetMarkerSize: Size.square(50), 54 | ), 55 | driverMarkerIconInfo: MarkerIconInfo( 56 | infoWindowTitle: "Alex", 57 | assetPath: "assets/images/driver-marker-icon.png", 58 | onTapMarker: (currentLocation) { 59 | debugPrint("Driver is currently at $currentLocation"); 60 | }, 61 | assetMarkerSize: Size.square(50), 62 | rotation: 90, 63 | ), 64 | onPolylineUpdate: (p) { 65 | debugPrint("Polyline updated: ${p.points}"); 66 | }, 67 | updatePolylinesOnDriverLocUpdate: true, 68 | // mock stream 69 | driverCoordinatesStream: Stream.periodic( 70 | Duration(milliseconds: 500), 71 | (i) => LatLng( 72 | 40.47747872288886 + i / 10000, 73 | -3.368043154478073 - i / 10000, 74 | ), 75 | ), 76 | totalTimeCallback: (time) => debugPrint(time), 77 | totalDistanceCallback: (distance) => debugPrint(distance), 78 | ), 79 | ), 80 | // demonstrates how to interact with the controller 81 | Padding( 82 | padding: const EdgeInsets.all(10), 83 | child: Row( 84 | children: [ 85 | Expanded( 86 | child: ElevatedButton( 87 | onPressed: () { 88 | mapsWidgetController.currentState!.setSourceLatLng( 89 | LatLng( 90 | 40.484000837597925 * (Random().nextDouble()), 91 | -3.369978368282318, 92 | ), 93 | ); 94 | }, 95 | child: Text('Update source'), 96 | ), 97 | ), 98 | const SizedBox(width: 10), 99 | Expanded( 100 | child: ElevatedButton( 101 | onPressed: () async { 102 | final googleMapsCon = await mapsWidgetController 103 | .currentState! 104 | .getGoogleMapsController(); 105 | googleMapsCon.showMarkerInfoWindow( 106 | MarkerIconInfo.sourceMarkerId, 107 | ); 108 | }, 109 | child: Text('Show source info'), 110 | ), 111 | ), 112 | ], 113 | ), 114 | ), 115 | ], 116 | ), 117 | ), 118 | ), 119 | ); 120 | } 121 | } 122 | -------------------------------------------------------------------------------- /example/pubspec.lock: -------------------------------------------------------------------------------- 1 | # Generated by pub 2 | # See https://dart.dev/tools/pub/glossary#lockfile 3 | packages: 4 | async: 5 | dependency: transitive 6 | description: 7 | name: async 8 | sha256: "947bfcf187f74dbc5e146c9eb9c0f10c9f8b30743e341481c1e2ed3ecc18c20c" 9 | url: "https://pub.dev" 10 | source: hosted 11 | version: "2.11.0" 12 | characters: 13 | dependency: transitive 14 | description: 15 | name: characters 16 | sha256: "04a925763edad70e8443c99234dc3328f442e811f1d8fd1a72f1c8ad0f69a605" 17 | url: "https://pub.dev" 18 | source: hosted 19 | version: "1.3.0" 20 | collection: 21 | dependency: transitive 22 | description: 23 | name: collection 24 | sha256: ee67cb0715911d28db6bf4af1026078bd6f0128b07a5f66fb2ed94ec6783c09a 25 | url: "https://pub.dev" 26 | source: hosted 27 | version: "1.18.0" 28 | csslib: 29 | dependency: transitive 30 | description: 31 | name: csslib 32 | sha256: "706b5707578e0c1b4b7550f64078f0a0f19dec3f50a178ffae7006b0a9ca58fb" 33 | url: "https://pub.dev" 34 | source: hosted 35 | version: "1.0.0" 36 | dio: 37 | dependency: transitive 38 | description: 39 | name: dio 40 | sha256: "5598aa796bbf4699afd5c67c0f5f6e2ed542afc956884b9cd58c306966efc260" 41 | url: "https://pub.dev" 42 | source: hosted 43 | version: "5.7.0" 44 | dio_web_adapter: 45 | dependency: transitive 46 | description: 47 | name: dio_web_adapter 48 | sha256: "33259a9276d6cea88774a0000cfae0d861003497755969c92faa223108620dc8" 49 | url: "https://pub.dev" 50 | source: hosted 51 | version: "2.0.0" 52 | flutter: 53 | dependency: "direct main" 54 | description: flutter 55 | source: sdk 56 | version: "0.0.0" 57 | flutter_lints: 58 | dependency: "direct dev" 59 | description: 60 | name: flutter_lints 61 | sha256: "5398f14efa795ffb7a33e9b6a08798b26a180edac4ad7db3f231e40f82ce11e1" 62 | url: "https://pub.dev" 63 | source: hosted 64 | version: "5.0.0" 65 | flutter_plugin_android_lifecycle: 66 | dependency: transitive 67 | description: 68 | name: flutter_plugin_android_lifecycle 69 | sha256: "9ee02950848f61c4129af3d6ec84a1cfc0e47931abc746b03e7a3bc3e8ff6eda" 70 | url: "https://pub.dev" 71 | source: hosted 72 | version: "2.0.22" 73 | flutter_web_plugins: 74 | dependency: transitive 75 | description: flutter 76 | source: sdk 77 | version: "0.0.0" 78 | google_maps: 79 | dependency: transitive 80 | description: 81 | name: google_maps 82 | sha256: "4d6e199c561ca06792c964fa24b2bac7197bf4b401c2e1d23e345e5f9939f531" 83 | url: "https://pub.dev" 84 | source: hosted 85 | version: "8.1.1" 86 | google_maps_flutter: 87 | dependency: transitive 88 | description: 89 | name: google_maps_flutter 90 | sha256: "209856c8e5571626afba7182cf634b2910069dc567954e76ec3e3fb37f5e9db3" 91 | url: "https://pub.dev" 92 | source: hosted 93 | version: "2.10.0" 94 | google_maps_flutter_android: 95 | dependency: transitive 96 | description: 97 | name: google_maps_flutter_android 98 | sha256: "10cf27bee8c560f8e69992b3a0f27ddf1d7acbea622ddb13ef3f587848a73f26" 99 | url: "https://pub.dev" 100 | source: hosted 101 | version: "2.14.7" 102 | google_maps_flutter_ios: 103 | dependency: transitive 104 | description: 105 | name: google_maps_flutter_ios 106 | sha256: "3a484846fc56f15e47e3de1f5ea80a7ff2b31721d2faa88f390f3b3cf580c953" 107 | url: "https://pub.dev" 108 | source: hosted 109 | version: "2.13.0" 110 | google_maps_flutter_platform_interface: 111 | dependency: transitive 112 | description: 113 | name: google_maps_flutter_platform_interface 114 | sha256: faf05935c2714445ae23ca16af523beba7bd5418c4c74798d67144f562df3e87 115 | url: "https://pub.dev" 116 | source: hosted 117 | version: "2.9.3" 118 | google_maps_flutter_web: 119 | dependency: transitive 120 | description: 121 | name: google_maps_flutter_web 122 | sha256: ff39211bd25d7fad125d19f757eba85bd154460907cd4d135e07e3d0f98a4130 123 | url: "https://pub.dev" 124 | source: hosted 125 | version: "0.5.10" 126 | google_maps_widget: 127 | dependency: "direct main" 128 | description: 129 | path: ".." 130 | relative: true 131 | source: path 132 | version: "1.0.6" 133 | html: 134 | dependency: transitive 135 | description: 136 | name: html 137 | sha256: "3a7812d5bcd2894edf53dfaf8cd640876cf6cef50a8f238745c8b8120ea74d3a" 138 | url: "https://pub.dev" 139 | source: hosted 140 | version: "0.15.4" 141 | http_parser: 142 | dependency: transitive 143 | description: 144 | name: http_parser 145 | sha256: "2aa08ce0341cc9b354a498388e30986515406668dbcc4f7c950c3e715496693b" 146 | url: "https://pub.dev" 147 | source: hosted 148 | version: "4.0.2" 149 | lints: 150 | dependency: transitive 151 | description: 152 | name: lints 153 | sha256: "3315600f3fb3b135be672bf4a178c55f274bebe368325ae18462c89ac1e3b413" 154 | url: "https://pub.dev" 155 | source: hosted 156 | version: "5.0.0" 157 | material_color_utilities: 158 | dependency: transitive 159 | description: 160 | name: material_color_utilities 161 | sha256: f7142bb1154231d7ea5f96bc7bde4bda2a0945d2806bb11670e30b850d56bdec 162 | url: "https://pub.dev" 163 | source: hosted 164 | version: "0.11.1" 165 | meta: 166 | dependency: transitive 167 | description: 168 | name: meta 169 | sha256: bdb68674043280c3428e9ec998512fb681678676b3c54e773629ffe74419f8c7 170 | url: "https://pub.dev" 171 | source: hosted 172 | version: "1.15.0" 173 | path: 174 | dependency: transitive 175 | description: 176 | name: path 177 | sha256: "087ce49c3f0dc39180befefc60fdb4acd8f8620e5682fe2476afd0b3688bb4af" 178 | url: "https://pub.dev" 179 | source: hosted 180 | version: "1.9.0" 181 | plugin_platform_interface: 182 | dependency: transitive 183 | description: 184 | name: plugin_platform_interface 185 | sha256: "4820fbfdb9478b1ebae27888254d445073732dae3d6ea81f0b7e06d5dedc3f02" 186 | url: "https://pub.dev" 187 | source: hosted 188 | version: "2.1.8" 189 | sanitize_html: 190 | dependency: transitive 191 | description: 192 | name: sanitize_html 193 | sha256: "12669c4a913688a26555323fb9cec373d8f9fbe091f2d01c40c723b33caa8989" 194 | url: "https://pub.dev" 195 | source: hosted 196 | version: "2.1.0" 197 | sky_engine: 198 | dependency: transitive 199 | description: flutter 200 | source: sdk 201 | version: "0.0.99" 202 | source_span: 203 | dependency: transitive 204 | description: 205 | name: source_span 206 | sha256: "53e943d4206a5e30df338fd4c6e7a077e02254531b138a15aec3bd143c1a8b3c" 207 | url: "https://pub.dev" 208 | source: hosted 209 | version: "1.10.0" 210 | stream_transform: 211 | dependency: transitive 212 | description: 213 | name: stream_transform 214 | sha256: "14a00e794c7c11aa145a170587321aedce29769c08d7f58b1d141da75e3b1c6f" 215 | url: "https://pub.dev" 216 | source: hosted 217 | version: "2.1.0" 218 | string_scanner: 219 | dependency: transitive 220 | description: 221 | name: string_scanner 222 | sha256: "688af5ed3402a4bde5b3a6c15fd768dbf2621a614950b17f04626c431ab3c4c3" 223 | url: "https://pub.dev" 224 | source: hosted 225 | version: "1.3.0" 226 | term_glyph: 227 | dependency: transitive 228 | description: 229 | name: term_glyph 230 | sha256: a29248a84fbb7c79282b40b8c72a1209db169a2e0542bce341da992fe1bc7e84 231 | url: "https://pub.dev" 232 | source: hosted 233 | version: "1.2.1" 234 | typed_data: 235 | dependency: transitive 236 | description: 237 | name: typed_data 238 | sha256: facc8d6582f16042dd49f2463ff1bd6e2c9ef9f3d5da3d9b087e244a7b564b3c 239 | url: "https://pub.dev" 240 | source: hosted 241 | version: "1.3.2" 242 | vector_math: 243 | dependency: transitive 244 | description: 245 | name: vector_math 246 | sha256: "80b3257d1492ce4d091729e3a67a60407d227c27241d6927be0130c98e741803" 247 | url: "https://pub.dev" 248 | source: hosted 249 | version: "2.1.4" 250 | web: 251 | dependency: transitive 252 | description: 253 | name: web 254 | sha256: cd3543bd5798f6ad290ea73d210f423502e71900302dde696f8bff84bf89a1cb 255 | url: "https://pub.dev" 256 | source: hosted 257 | version: "1.1.0" 258 | sdks: 259 | dart: ">=3.5.3 <4.0.0" 260 | flutter: ">=3.22.0" 261 | -------------------------------------------------------------------------------- /example/pubspec.yaml: -------------------------------------------------------------------------------- 1 | name: google_maps_widget_demo 2 | description: "A new Flutter application to show the demo for google_maps_widget package." 3 | 4 | publish_to: 'none' 5 | 6 | version: 1.0.0+1 7 | 8 | environment: 9 | sdk: ^3.5.3 10 | 11 | dependencies: 12 | flutter: 13 | sdk: flutter 14 | 15 | google_maps_widget: 16 | path: "../" 17 | 18 | dev_dependencies: 19 | flutter_lints: ^5.0.0 20 | 21 | flutter: 22 | uses-material-design: true 23 | assets: 24 | - assets/images/ -------------------------------------------------------------------------------- /lib/google_maps_widget.dart: -------------------------------------------------------------------------------- 1 | library; 2 | 3 | export 'src/main_widget.dart'; 4 | export 'src/models/marker_icon_info.dart'; 5 | export 'package:google_maps_flutter/google_maps_flutter.dart'; 6 | -------------------------------------------------------------------------------- /lib/src/main_widget.dart: -------------------------------------------------------------------------------- 1 | import 'dart:async'; 2 | 3 | import 'package:flutter/foundation.dart'; 4 | import 'package:flutter/gestures.dart'; 5 | import 'package:flutter/material.dart'; 6 | import 'package:google_maps_flutter/google_maps_flutter.dart'; 7 | import 'package:google_maps_widget/src/models/direction.dart'; 8 | import 'package:google_maps_widget/src/models/marker_icon_info.dart'; 9 | import 'package:google_maps_widget/src/utils/constants.dart'; 10 | 11 | /// A [GoogleMapsWidget] which can be used to make polylines(route) 12 | /// from a source to a destination, 13 | /// and also handle a driver's realtime location (if any) on the map. 14 | class GoogleMapsWidget extends StatefulWidget { 15 | const GoogleMapsWidget({ 16 | super.key, 17 | required this.apiKey, 18 | required this.sourceLatLng, 19 | required this.destinationLatLng, 20 | this.totalDistanceCallback, 21 | this.totalTimeCallback, 22 | this.onMapCreated, 23 | this.sourceMarkerIconInfo = const MarkerIconInfo(), 24 | this.destinationMarkerIconInfo = const MarkerIconInfo(), 25 | this.driverMarkerIconInfo = const MarkerIconInfo(), 26 | this.driverCoordinatesStream, 27 | this.defaultCameraLocation, 28 | this.onPolylineUpdate, 29 | this.markers = const {}, 30 | this.polylines = const {}, 31 | this.showPolyline = true, 32 | this.defaultCameraZoom = Constants.kDefaultCameraZoom, 33 | this.routeColor = Constants.kRouteColor, 34 | this.routeWidth = Constants.kRouteWidth, 35 | this.updatePolylinesOnDriverLocUpdate = true, 36 | 37 | // other google maps params 38 | this.gestureRecognizers = const >{}, 39 | this.layoutDirection, 40 | this.compassEnabled = true, 41 | this.mapToolbarEnabled = true, 42 | this.cameraTargetBounds = CameraTargetBounds.unbounded, 43 | this.mapType = MapType.normal, 44 | this.minMaxZoomPreference = MinMaxZoomPreference.unbounded, 45 | this.rotateGesturesEnabled = true, 46 | this.scrollGesturesEnabled = true, 47 | this.zoomControlsEnabled = true, 48 | this.zoomGesturesEnabled = true, 49 | this.liteModeEnabled = false, 50 | this.tiltGesturesEnabled = true, 51 | this.myLocationEnabled = false, 52 | this.myLocationButtonEnabled = true, 53 | this.padding = const EdgeInsets.all(0), 54 | this.indoorViewEnabled = false, 55 | this.trafficEnabled = false, 56 | this.buildingsEnabled = true, 57 | this.polygons = const {}, 58 | this.circles = const {}, 59 | this.onCameraMoveStarted, 60 | this.tileOverlays = const {}, 61 | this.onCameraMove, 62 | this.onCameraIdle, 63 | this.onTap, 64 | this.onLongPress, 65 | }); 66 | 67 | /// Google Maps API Key. 68 | final String apiKey; 69 | 70 | /// The source [LatLng]. 71 | final LatLng sourceLatLng; 72 | 73 | /// The destination [LatLng]. 74 | final LatLng destinationLatLng; 75 | 76 | /// If true, Updates the polylines everytime a new event is pushed to 77 | /// the driver stream, i.e. the driver location changes.. 78 | /// 79 | /// Valid only if [GoogleMapsWidget.driverCoordinatesStream] is not null. 80 | final bool updatePolylinesOnDriverLocUpdate; 81 | 82 | /// Called after polylines are created for the given 83 | /// [sourceLatLng] and [destinationLatLng] and 84 | /// totalTime is initialized. 85 | final void Function(String?)? totalTimeCallback; 86 | 87 | /// Called after polylines are created for the given 88 | /// [sourceLatLng] and [destinationLatLng] and 89 | /// totalDistance is initialized. 90 | final void Function(String?)? totalDistanceCallback; 91 | 92 | /// A [Stream] of [LatLng] objects for the driver 93 | /// used to render [driverMarkerIconInfo] on the map 94 | /// with the provided [LatLng] objects. 95 | /// 96 | /// See also: 97 | /// * [onTapDriverInfoWindow] parameter. 98 | /// * [onTapDriverMarker] parameter. 99 | /// * [driverName] parameter. 100 | /// 101 | /// If null, the [driverMarkerIconInfo] is not rendered. 102 | final Stream? driverCoordinatesStream; 103 | 104 | /// The initial location of the map's camera. 105 | /// If null, initial location is [sourceLatLng]. 106 | final LatLng? defaultCameraLocation; 107 | 108 | /// The initial zoom of the map's camera. 109 | /// Defaults to [Constants.kDefaultCameraZoom]. 110 | final double defaultCameraZoom; 111 | 112 | /// Color of the route made between [sourceLatLng] and [destinationLatLng]. 113 | /// Defaults to [Constants.kRouteColor]. 114 | final Color routeColor; 115 | 116 | /// Width of the route made between [sourceLatLng] and [destinationLatLng]. 117 | /// Defaults to [Constants.kRouteWidth]. 118 | final int routeWidth; 119 | 120 | /// Called when the polyline is updated i.e. route is updated. 121 | final void Function(Polyline)? onPolylineUpdate; 122 | 123 | /// The marker which is rendered on the location [sourceLatLng]. 124 | final MarkerIconInfo sourceMarkerIconInfo; 125 | 126 | /// The marker which is rendered on the location [destinationLatLng]. 127 | final MarkerIconInfo destinationMarkerIconInfo; 128 | 129 | /// The marker which is rendered on the driver's current location 130 | /// provided by [driverCoordinatesStream]. 131 | /// 132 | /// See also: 133 | /// * [driverCoordinatesStream] parameter. 134 | final MarkerIconInfo driverMarkerIconInfo; 135 | 136 | /// Whether to show the generated polyline from [sourceLatLng] 137 | /// to [destinationLatLng]. 138 | /// 139 | /// Defaults to true. 140 | final bool showPolyline; 141 | 142 | /// Callback method for when the map is ready to be used. 143 | /// 144 | /// Used to receive a [GoogleMapController] for this [GoogleMap]. 145 | final void Function(GoogleMapController)? onMapCreated; 146 | 147 | ///////////////////////////////////////////////// 148 | // OTHER GOOGLE MAPS PARAMS 149 | ///////////////////////////////////////////////// 150 | 151 | /// True if the map view should respond to rotate gestures. 152 | final bool rotateGesturesEnabled; 153 | 154 | /// True if the map view should respond to scroll gestures. 155 | final bool scrollGesturesEnabled; 156 | 157 | /// True if the map view should show zoom controls. This includes two buttons 158 | /// to zoom in and zoom out. The default value is to show zoom controls. 159 | /// 160 | /// This is only supported on Android. And this field is silently ignored on iOS. 161 | final bool zoomControlsEnabled; 162 | 163 | /// True if the map view should respond to zoom gestures. 164 | final bool zoomGesturesEnabled; 165 | 166 | /// True if the map view should be in lite mode. Android only. 167 | /// 168 | /// See https://developers.google.com/maps/documentation/android-sdk/lite#overview_of_lite_mode for more details. 169 | final bool liteModeEnabled; 170 | 171 | /// True if the map view should respond to tilt gestures. 172 | final bool tiltGesturesEnabled; 173 | 174 | /// True if a "My Location" layer should be shown on the map. 175 | /// 176 | /// This layer includes a location indicator at the current device location, 177 | /// as well as a My Location button. 178 | /// * The indicator is a small blue dot if the device is stationary, or a 179 | /// chevron if the device is moving. 180 | /// * The My Location button animates to focus on the user's current location 181 | /// if the user's location is currently known. 182 | /// 183 | /// Enabling this feature requires adding location permissions to both native 184 | /// platforms of your app. 185 | /// * On Android add either 186 | /// `` 187 | /// or `` 188 | /// to your `AndroidManifest.xml` file. `ACCESS_COARSE_LOCATION` returns a 189 | /// location with an accuracy approximately equivalent to a city block, while 190 | /// `ACCESS_FINE_LOCATION` returns as precise a location as possible, although 191 | /// it consumes more battery power. You will also need to request these 192 | /// permissions during run-time. If they are not granted, the My Location 193 | /// feature will fail silently. 194 | /// * On iOS add a `NSLocationWhenInUseUsageDescription` key to your 195 | /// `Info.plist` file. This will automatically prompt the user for permissions 196 | /// when the map tries to turn on the My Location layer. 197 | final bool myLocationEnabled; 198 | 199 | /// Enables or disables the my-location button. 200 | /// 201 | /// The my-location button causes the camera to move such that the user's 202 | /// location is in the center of the map. If the button is enabled, it is 203 | /// only shown when the my-location layer is enabled. 204 | /// 205 | /// By default, the my-location button is enabled (and hence shown when the 206 | /// my-location layer is enabled). 207 | /// 208 | /// See also: 209 | /// * [myLocationEnabled] parameter. 210 | final bool myLocationButtonEnabled; 211 | 212 | /// Enables or disables the indoor view from the map 213 | final bool indoorViewEnabled; 214 | 215 | /// Enables or disables the traffic layer of the map 216 | final bool trafficEnabled; 217 | 218 | /// Enables or disables showing 3D buildings where available 219 | final bool buildingsEnabled; 220 | 221 | /// The layout direction to use for the embedded view. 222 | /// 223 | /// If this is null, the ambient [Directionality] is used instead. If there is 224 | /// no ambient [Directionality], [TextDirection.ltr] is used. 225 | final TextDirection? layoutDirection; 226 | 227 | /// True if the map should show a compass when rotated. 228 | final bool compassEnabled; 229 | 230 | /// True if the map should show a toolbar when you interact with the map. Android only. 231 | final bool mapToolbarEnabled; 232 | 233 | /// Called every time a [GoogleMap] is tapped. 234 | final ArgumentCallback? onTap; 235 | 236 | /// Called when camera movement has ended, there are no pending 237 | /// animations and the user has stopped interacting with the map. 238 | final VoidCallback? onCameraIdle; 239 | 240 | /// Called repeatedly as the camera continues to move after an 241 | /// onCameraMoveStarted call. 242 | /// 243 | /// This may be called as often as once every frame and should 244 | /// not perform expensive operations. 245 | final CameraPositionCallback? onCameraMove; 246 | 247 | /// Called when the camera starts moving. 248 | /// 249 | /// This can be initiated by the following: 250 | /// 1. Non-gesture animation initiated in response to user actions. 251 | /// For example: zoom buttons, my location button, or marker clicks. 252 | /// 2. Programmatically initiated animation. 253 | /// 3. Camera motion initiated in response to user gestures on the map. 254 | /// For example: pan, tilt, pinch to zoom, or rotate. 255 | final VoidCallback? onCameraMoveStarted; 256 | 257 | /// Called every time a [GoogleMap] is long pressed. 258 | final ArgumentCallback? onLongPress; 259 | 260 | /// Which gestures should be consumed by the map. 261 | /// 262 | /// It is possible for other gesture recognizers to be competing with the map on pointer 263 | /// events, e.g if the map is inside a [ListView] the [ListView] will want to handle 264 | /// vertical drags. The map will claim gestures that are recognized by any of the 265 | /// recognizers on this list. 266 | /// 267 | /// When this set is empty, the map will only handle pointer events for gestures that 268 | /// were not claimed by any other gesture recognizer. 269 | final Set> gestureRecognizers; 270 | 271 | /// Polygons to be placed on the map. 272 | final Set polygons; 273 | 274 | /// Circles to be placed on the map. 275 | final Set circles; 276 | 277 | /// Markers to be placed on the map. (apart from the source and destination markers). 278 | final Set markers; 279 | 280 | /// Polylines to be placed on the map. (apart from the one generated 281 | /// between the [sourceLatLng] and the [destinationLatLng]. 282 | /// 283 | /// You can disable the generated polyline by setting the [showPolyline] to false. 284 | final Set polylines; 285 | 286 | /// Tile overlays to be placed on the map. 287 | final Set tileOverlays; 288 | 289 | /// Type of map tiles to be rendered. 290 | final MapType mapType; 291 | 292 | /// Padding to be set on map. See https://developers.google.com/maps/documentation/android-sdk/map#map_padding for more details. 293 | final EdgeInsets padding; 294 | 295 | /// Preferred bounds for the camera zoom level. 296 | /// 297 | /// Actual bounds depend on map data and device. 298 | final MinMaxZoomPreference minMaxZoomPreference; 299 | 300 | /// Geographical bounding box for the camera target. 301 | final CameraTargetBounds cameraTargetBounds; 302 | 303 | @override 304 | GoogleMapsWidgetState createState() => GoogleMapsWidgetState(); 305 | } 306 | 307 | class GoogleMapsWidgetState extends State { 308 | /// Markers to be placed on the map. 309 | final _markersMap = {}; 310 | 311 | /// Polylines to be placed on the map. 312 | final _polylines = {}; 313 | 314 | final _mapsControllerCompleter = Completer(); 315 | 316 | Future getGoogleMapsController() => 317 | _mapsControllerCompleter.future; 318 | 319 | Future setSourceLatLng(LatLng sourceLatLng) async { 320 | if (_sourceLatLng == sourceLatLng) return; 321 | 322 | _sourceLatLng = sourceLatLng; 323 | await _buildPolyLines(); 324 | _setSourceDestinationMarkers(); 325 | setState(() {}); 326 | } 327 | 328 | Future setDestinationLatLng(LatLng destinationLatLng) async { 329 | if (_destinationLatLng == destinationLatLng) return; 330 | 331 | _destinationLatLng = destinationLatLng; 332 | await _buildPolyLines(); 333 | _setSourceDestinationMarkers(); 334 | setState(() {}); 335 | } 336 | 337 | StreamSubscription? _driverCoordinatesStreamSubscription; 338 | 339 | late LatLng _sourceLatLng; 340 | late LatLng _destinationLatLng; 341 | 342 | /// setting source and destination markers 343 | void _setSourceDestinationMarkers() async { 344 | _markersMap.remove(MarkerIconInfo.sourceMarkerId); 345 | 346 | final sourceMarker = widget.sourceMarkerIconInfo; 347 | if (sourceMarker.isVisible) { 348 | _markersMap[MarkerIconInfo.sourceMarkerId] = Marker( 349 | markerId: MarkerIconInfo.sourceMarkerId, 350 | position: _sourceLatLng, 351 | anchor: sourceMarker.anchor, 352 | rotation: sourceMarker.rotation, 353 | icon: await sourceMarker.bitmapDescriptor, 354 | onTap: sourceMarker.onTapMarker == null 355 | ? null 356 | : () => sourceMarker.onTapMarker!(_sourceLatLng), 357 | infoWindow: InfoWindow( 358 | onTap: sourceMarker.onTapInfoWindow == null 359 | ? null 360 | : () => sourceMarker.onTapInfoWindow!(_sourceLatLng), 361 | title: sourceMarker.infoWindowTitle, 362 | ), 363 | ); 364 | } 365 | 366 | _markersMap.remove(MarkerIconInfo.destinationMarkerId); 367 | 368 | final destinationMarker = widget.destinationMarkerIconInfo; 369 | if (destinationMarker.isVisible) { 370 | _markersMap[MarkerIconInfo.destinationMarkerId] = Marker( 371 | markerId: MarkerIconInfo.destinationMarkerId, 372 | position: _destinationLatLng, 373 | anchor: destinationMarker.anchor, 374 | rotation: destinationMarker.rotation, 375 | icon: await destinationMarker.bitmapDescriptor, 376 | onTap: destinationMarker.onTapMarker == null 377 | ? null 378 | : () => destinationMarker.onTapMarker!(_destinationLatLng), 379 | infoWindow: InfoWindow( 380 | onTap: destinationMarker.onTapInfoWindow == null 381 | ? null 382 | : () => destinationMarker.onTapInfoWindow!(_destinationLatLng), 383 | title: destinationMarker.infoWindowTitle, 384 | ), 385 | ); 386 | } 387 | 388 | setState(() {}); 389 | } 390 | 391 | /// Build polylines from [_sourceLatLng] to [_destinationLatLng]. 392 | Future _buildPolyLines({LatLng? driverLoc}) async { 393 | if (!widget.showPolyline) return; 394 | 395 | final result = await Direction.getDirections( 396 | googleMapsApiKey: widget.apiKey, 397 | origin: driverLoc ?? _sourceLatLng, 398 | destination: _destinationLatLng, 399 | ); 400 | 401 | final polylineCoordinates = []; 402 | 403 | if (result != null && result.polylinePoints.isNotEmpty) { 404 | polylineCoordinates.addAll(result.polylinePoints); 405 | } 406 | 407 | final polyline = Polyline( 408 | polylineId: const PolylineId('default-polyline'), 409 | color: widget.routeColor, 410 | width: widget.routeWidth, 411 | points: polylineCoordinates, 412 | ); 413 | 414 | widget.onPolylineUpdate?.call(polyline); 415 | 416 | if (driverLoc != null) _polylines.clear(); 417 | _polylines.add(polyline); 418 | 419 | // setting map such as both source and 420 | // destinations markers can be seen 421 | if (result != null) { 422 | final controller = await getGoogleMapsController(); 423 | 424 | controller.animateCamera( 425 | CameraUpdate.newLatLngBounds(result.bounds, 32), 426 | ); 427 | 428 | widget.totalTimeCallback?.call(result.totalDuration); 429 | widget.totalDistanceCallback?.call(result.totalDistance); 430 | } 431 | 432 | setState(() {}); 433 | } 434 | 435 | /// This function uses [GoogleMapsWidget.driverCoordinatesStream] which 436 | /// is a [Stream] of [LatLng]-[coordinates] and renders 437 | /// [GoogleMapsWidget.driverMarkerIconInfo] marker to show 438 | /// driver's location in realtime. 439 | Future _listenToDriverCoordinates() async { 440 | final driverStream = widget.driverCoordinatesStream; 441 | if (driverStream == null) return; 442 | 443 | final driverMarkerBitmapDescriptor = 444 | await widget.driverMarkerIconInfo.bitmapDescriptor; 445 | 446 | _driverCoordinatesStreamSubscription = driverStream.listen((coordinate) { 447 | if (widget.updatePolylinesOnDriverLocUpdate) { 448 | _buildPolyLines(driverLoc: coordinate); 449 | } 450 | 451 | if (!widget.driverMarkerIconInfo.isVisible) return; 452 | 453 | _markersMap.remove(MarkerIconInfo.driverMarkerId); 454 | 455 | final driverMarker = widget.driverMarkerIconInfo; 456 | _markersMap[MarkerIconInfo.driverMarkerId] = Marker( 457 | markerId: MarkerIconInfo.driverMarkerId, 458 | position: coordinate, 459 | anchor: driverMarker.anchor, 460 | rotation: driverMarker.rotation, 461 | icon: driverMarkerBitmapDescriptor, 462 | onTap: driverMarker.onTapMarker == null 463 | ? null 464 | : () => driverMarker.onTapMarker!(coordinate), 465 | infoWindow: InfoWindow( 466 | onTap: driverMarker.onTapInfoWindow == null 467 | ? null 468 | : () => driverMarker.onTapInfoWindow!(coordinate), 469 | title: driverMarker.infoWindowTitle, 470 | ), 471 | ); 472 | 473 | setState(() {}); 474 | }); 475 | } 476 | 477 | @override 478 | void initState() { 479 | _sourceLatLng = widget.sourceLatLng; 480 | _destinationLatLng = widget.destinationLatLng; 481 | 482 | _setSourceDestinationMarkers(); 483 | _buildPolyLines(); 484 | _listenToDriverCoordinates(); 485 | 486 | super.initState(); 487 | } 488 | 489 | @override 490 | void dispose() { 491 | _driverCoordinatesStreamSubscription?.cancel(); 492 | 493 | if (_mapsControllerCompleter.isCompleted) { 494 | _mapsControllerCompleter.future.then( 495 | (controller) => controller.dispose(), 496 | ); 497 | } 498 | 499 | super.dispose(); 500 | } 501 | 502 | @override 503 | Widget build(BuildContext context) { 504 | return GoogleMap( 505 | initialCameraPosition: CameraPosition( 506 | target: widget.defaultCameraLocation ?? _sourceLatLng, 507 | zoom: widget.defaultCameraZoom, 508 | ), 509 | markers: {..._markersMap.values, ...widget.markers}, 510 | polylines: {..._polylines, ...widget.polylines}, 511 | onMapCreated: (controller) { 512 | _mapsControllerCompleter.complete(controller); 513 | if (widget.onMapCreated != null) { 514 | return widget.onMapCreated!(controller); 515 | } 516 | }, 517 | ///////////////////////////////////////////////// 518 | // OTHER GOOGLE MAPS PARAMS 519 | ///////////////////////////////////////////////// 520 | gestureRecognizers: widget.gestureRecognizers, 521 | compassEnabled: widget.compassEnabled, 522 | layoutDirection: widget.layoutDirection, 523 | mapToolbarEnabled: widget.mapToolbarEnabled, 524 | cameraTargetBounds: widget.cameraTargetBounds, 525 | mapType: widget.mapType, 526 | minMaxZoomPreference: widget.minMaxZoomPreference, 527 | rotateGesturesEnabled: widget.rotateGesturesEnabled, 528 | scrollGesturesEnabled: widget.scrollGesturesEnabled, 529 | zoomControlsEnabled: widget.zoomControlsEnabled, 530 | zoomGesturesEnabled: widget.zoomGesturesEnabled, 531 | liteModeEnabled: widget.liteModeEnabled, 532 | tiltGesturesEnabled: widget.tiltGesturesEnabled, 533 | myLocationEnabled: widget.myLocationEnabled, 534 | myLocationButtonEnabled: widget.myLocationButtonEnabled, 535 | padding: widget.padding, 536 | indoorViewEnabled: widget.indoorViewEnabled, 537 | trafficEnabled: widget.trafficEnabled, 538 | buildingsEnabled: widget.buildingsEnabled, 539 | polygons: widget.polygons, 540 | circles: widget.circles, 541 | onCameraMoveStarted: widget.onCameraMoveStarted, 542 | tileOverlays: widget.tileOverlays, 543 | onCameraMove: widget.onCameraMove, 544 | onCameraIdle: widget.onCameraIdle, 545 | onTap: widget.onTap, 546 | onLongPress: widget.onLongPress, 547 | ); 548 | } 549 | } 550 | -------------------------------------------------------------------------------- /lib/src/models/direction.dart: -------------------------------------------------------------------------------- 1 | import 'package:dio/dio.dart'; 2 | import 'package:google_maps_flutter/google_maps_flutter.dart'; 3 | 4 | /// A class containing information required by [GoogleMap] to 5 | /// draw polylines on the map widget. 6 | class Direction { 7 | const Direction._({ 8 | required this.bounds, 9 | required this.polylinePoints, 10 | required this.totalDistance, 11 | required this.totalDuration, 12 | }); 13 | 14 | /// A latitude/longitude aligned rectangle. 15 | /// Used to animate and position the camera in such a 16 | /// way that both the source and the destinations markers are visible. 17 | final LatLngBounds bounds; 18 | 19 | /// A [List] of [LatLng] objects required by [GoogleMap] 20 | /// to display the route. 21 | final List polylinePoints; 22 | 23 | /// The total distance between the source and the destination. 24 | final String totalDistance; 25 | 26 | /// The total time between the source and the destination. 27 | final String totalDuration; 28 | 29 | /// Google Maps API base url. 30 | static const String _baseUrl = 31 | 'https://maps.googleapis.com/maps/api/directions/json?'; 32 | 33 | /// Receives [origin], [destination], [googleMapsApiKey] coordinates 34 | /// and calls the Google Maps API. 35 | static Future getDirections({ 36 | required String googleMapsApiKey, 37 | required LatLng origin, 38 | required LatLng destination, 39 | }) async { 40 | final response = await Dio().get( 41 | _baseUrl, 42 | queryParameters: { 43 | 'key': googleMapsApiKey, 44 | 'origin': '${origin.latitude},${origin.longitude}', 45 | 'destination': '${destination.latitude},${destination.longitude}', 46 | }, 47 | ); 48 | 49 | if (response.statusCode == 200) { 50 | // no routes 51 | if ((response.data['routes'] as List).isEmpty) { 52 | return null; 53 | } else { 54 | return Direction._fromMap(response.data); 55 | } 56 | } else { 57 | return null; 58 | } 59 | } 60 | 61 | /// Takes in an [encoded] polyline string from the 62 | /// api response and parses the given string in a [List] of [LatLng]. 63 | static List _decodePolyline(String encoded) { 64 | List polyLines = []; 65 | int index = 0, len = encoded.length; 66 | int lat = 0, lng = 0; 67 | 68 | while (index < len) { 69 | int b, shift = 0, result = 0; 70 | do { 71 | b = encoded.codeUnitAt(index++) - 63; 72 | result |= (b & 0x1f) << shift; 73 | shift += 5; 74 | } while (b >= 0x20); 75 | int dLat = ((result & 1) != 0 ? ~(result >> 1) : (result >> 1)); 76 | lat += dLat; 77 | 78 | shift = 0; 79 | result = 0; 80 | do { 81 | b = encoded.codeUnitAt(index++) - 63; 82 | result |= (b & 0x1f) << shift; 83 | shift += 5; 84 | } while (b >= 0x20); 85 | int dLng = ((result & 1) != 0 ? ~(result >> 1) : (result >> 1)); 86 | lng += dLng; 87 | final p = LatLng((lat / 1E5).toDouble(), (lng / 1E5).toDouble()); 88 | polyLines.add(p); 89 | } 90 | return polyLines; 91 | } 92 | 93 | /// Private constructor for [Direction] which receives a map from the 94 | /// api request and maps the response to the class variables. 95 | factory Direction._fromMap(Map map) { 96 | // Get route information 97 | final data = Map.from(map['routes'][0]); 98 | 99 | // Bounds 100 | final northeast = data['bounds']['northeast']; 101 | final southwest = data['bounds']['southwest']; 102 | final bounds = LatLngBounds( 103 | northeast: LatLng(northeast['lat'], northeast['lng']), 104 | southwest: LatLng(southwest['lat'], southwest['lng']), 105 | ); 106 | 107 | // Distance & Duration 108 | String distance = ''; 109 | String duration = ''; 110 | if ((data['legs'] as List).isNotEmpty) { 111 | final leg = data['legs'][0]; 112 | distance = leg['distance']['text']; 113 | duration = leg['duration']['text']; 114 | } 115 | 116 | return Direction._( 117 | bounds: bounds, 118 | polylinePoints: _decodePolyline(data['overview_polyline']['points']), 119 | totalDistance: distance, 120 | totalDuration: duration, 121 | ); 122 | } 123 | } 124 | -------------------------------------------------------------------------------- /lib/src/models/marker_icon_info.dart: -------------------------------------------------------------------------------- 1 | import 'dart:ui'; 2 | 3 | import 'package:flutter/material.dart'; 4 | import 'package:flutter/services.dart'; 5 | import 'package:google_maps_flutter/google_maps_flutter.dart'; 6 | import 'package:google_maps_widget/src/utils/constants.dart'; 7 | 8 | /// Class used to provide information about the marker on the [GoogleMap] widget. 9 | /// Pass either an asset image [assetPath] or a material [icon] to change the appearance of the icon. 10 | /// [assetMarkerSize] can be provided to resize image at [assetPath]. 11 | /// 12 | /// See also: 13 | /// * [bitmapDescriptor] parameter. 14 | class MarkerIconInfo { 15 | const MarkerIconInfo({ 16 | this.icon, 17 | this.assetPath, 18 | this.assetMarkerSize, 19 | this.onTapMarker, 20 | this.onTapInfoWindow, 21 | this.infoWindowTitle, 22 | this.isVisible = true, 23 | this.rotation = 0.0, 24 | this.anchor = const Offset(0.5, 1.0), 25 | }); 26 | 27 | static const sourceMarkerId = MarkerId('source'); 28 | static const destinationMarkerId = MarkerId('destination'); 29 | static const driverMarkerId = MarkerId('driver'); 30 | 31 | /// Material icon that can be passed which can be used 32 | /// in place of a default [Marker]. 33 | final Icon? icon; 34 | 35 | /// Asset image path that can be passed which can be used 36 | /// in place of a default [Marker]. 37 | final String? assetPath; 38 | 39 | /// Asset marker size which can be used to 40 | /// resize image at [assetPath]. 41 | /// If null, defaults to [Constants.kDefaultMarkerSize]. 42 | final Size? assetMarkerSize; 43 | 44 | /// The icon image point that will be placed at the [position] of the marker. 45 | /// 46 | /// The image point is specified in normalized coordinates: An anchor of 47 | /// (0.0, 0.0) means the top left corner of the image. An anchor 48 | /// of (1.0, 1.0) means the bottom right corner of the image. 49 | final Offset anchor; 50 | 51 | /// Rotation of the marker image in degrees clockwise from the [anchor] point. 52 | final double rotation; 53 | 54 | /// Displays [Marker]'s [InfoWindow] displaying [infoWindowTitle] 55 | /// when tapped on [MarkerIconInfo]. 56 | /// 57 | /// The info window is not rendered if [infoWindowTitle] is null. 58 | /// 59 | /// Defaults to null. 60 | final String? infoWindowTitle; 61 | 62 | /// Whether to show the marker or the map or not. 63 | /// 64 | /// Defaults to true. 65 | final bool isVisible; 66 | 67 | /// Called every time the [Marker] is tapped. 68 | final void Function(LatLng)? onTapMarker; 69 | 70 | /// Called every time the [InfoWindow] is tapped. 71 | final void Function(LatLng)? onTapInfoWindow; 72 | 73 | /// This getter is used to get the [BitmapDescriptor] required 74 | /// by the [Marker]. 75 | /// 76 | /// If both [assetPath] and [icon] are passed, 77 | /// [BitmapDescriptor] created from [assetPath] is returned. 78 | /// 79 | /// If both [assetPath] and [icon] are not passed, 80 | /// then [BitmapDescriptor.defaultMarker] is returned. 81 | Future get bitmapDescriptor async { 82 | if (assetPath != null) { 83 | return await _getMarkerFromAsset( 84 | path: assetPath!, 85 | size: assetMarkerSize ?? Constants.kDefaultMarkerSize, 86 | ); 87 | } 88 | 89 | if (icon != null) { 90 | return await _getMarkerFromMaterialIcon( 91 | icon: icon!, 92 | size: assetMarkerSize ?? Constants.kDefaultMarkerSize, 93 | ); 94 | } 95 | 96 | return BitmapDescriptor.defaultMarker; 97 | } 98 | 99 | /// Creates a [BitmapDescriptor] from an asset image. 100 | /// 101 | /// [path] is the path of the image. 102 | /// [size] can be provided to resize the image. 103 | /// Defaults to [Constants.kDefaultMarkerSize] 104 | static Future _getMarkerFromAsset({ 105 | required String path, 106 | Size size = Constants.kDefaultMarkerSize, 107 | }) async { 108 | ByteData data = await rootBundle.load(path); 109 | Codec codec = await instantiateImageCodec( 110 | data.buffer.asUint8List(), 111 | targetWidth: size.width.toInt(), 112 | targetHeight: size.height.toInt(), 113 | ); 114 | FrameInfo fi = await codec.getNextFrame(); 115 | final bytes = (await fi.image.toByteData(format: ImageByteFormat.png))! 116 | .buffer 117 | .asUint8List(); 118 | 119 | return BitmapDescriptor.bytes( 120 | bytes, 121 | height: size.height, 122 | width: size.width, 123 | ); 124 | } 125 | 126 | /// Creates a [BitmapDescriptor] from a material [Icon]. 127 | static Future _getMarkerFromMaterialIcon({ 128 | required Icon icon, 129 | required Size size, 130 | }) async { 131 | final iconData = icon.icon!; 132 | final pictureRecorder = PictureRecorder(); 133 | final canvas = Canvas(pictureRecorder); 134 | final textPainter = TextPainter(textDirection: TextDirection.ltr); 135 | final iconStr = String.fromCharCode(iconData.codePoint); 136 | 137 | textPainter.text = TextSpan( 138 | text: iconStr, 139 | style: TextStyle( 140 | letterSpacing: 0.0, 141 | fontSize: 48.0, 142 | fontFamily: iconData.fontFamily, 143 | color: icon.color, 144 | ), 145 | ); 146 | textPainter.layout(); 147 | textPainter.paint(canvas, const Offset(0.0, 0.0)); 148 | 149 | final picture = pictureRecorder.endRecording(); 150 | final image = await picture.toImage( 151 | size.width.toInt(), 152 | size.height.toInt(), 153 | ); 154 | final bytes = await image.toByteData(format: ImageByteFormat.png); 155 | 156 | return BitmapDescriptor.bytes( 157 | bytes!.buffer.asUint8List(), 158 | height: size.height, 159 | width: size.width, 160 | ); 161 | } 162 | } 163 | -------------------------------------------------------------------------------- /lib/src/utils/constants.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:google_maps_widget/google_maps_widget.dart'; 3 | 4 | /// Defines all the constants used by [GoogleMapsWidget]. 5 | class Constants { 6 | Constants._(); 7 | 8 | static const kDefaultCameraZoom = 15.0; 9 | static const kRouteWidth = 5; 10 | static const kRouteColor = Colors.indigo; 11 | static const kDefaultMarkerSize = Size.square(150); 12 | } 13 | -------------------------------------------------------------------------------- /pubspec.lock: -------------------------------------------------------------------------------- 1 | # Generated by pub 2 | # See https://dart.dev/tools/pub/glossary#lockfile 3 | packages: 4 | async: 5 | dependency: transitive 6 | description: 7 | name: async 8 | sha256: "947bfcf187f74dbc5e146c9eb9c0f10c9f8b30743e341481c1e2ed3ecc18c20c" 9 | url: "https://pub.dev" 10 | source: hosted 11 | version: "2.11.0" 12 | characters: 13 | dependency: transitive 14 | description: 15 | name: characters 16 | sha256: "04a925763edad70e8443c99234dc3328f442e811f1d8fd1a72f1c8ad0f69a605" 17 | url: "https://pub.dev" 18 | source: hosted 19 | version: "1.3.0" 20 | collection: 21 | dependency: transitive 22 | description: 23 | name: collection 24 | sha256: ee67cb0715911d28db6bf4af1026078bd6f0128b07a5f66fb2ed94ec6783c09a 25 | url: "https://pub.dev" 26 | source: hosted 27 | version: "1.18.0" 28 | csslib: 29 | dependency: transitive 30 | description: 31 | name: csslib 32 | sha256: "706b5707578e0c1b4b7550f64078f0a0f19dec3f50a178ffae7006b0a9ca58fb" 33 | url: "https://pub.dev" 34 | source: hosted 35 | version: "1.0.0" 36 | dio: 37 | dependency: "direct main" 38 | description: 39 | name: dio 40 | sha256: "5598aa796bbf4699afd5c67c0f5f6e2ed542afc956884b9cd58c306966efc260" 41 | url: "https://pub.dev" 42 | source: hosted 43 | version: "5.7.0" 44 | dio_web_adapter: 45 | dependency: transitive 46 | description: 47 | name: dio_web_adapter 48 | sha256: "33259a9276d6cea88774a0000cfae0d861003497755969c92faa223108620dc8" 49 | url: "https://pub.dev" 50 | source: hosted 51 | version: "2.0.0" 52 | flutter: 53 | dependency: "direct main" 54 | description: flutter 55 | source: sdk 56 | version: "0.0.0" 57 | flutter_lints: 58 | dependency: "direct dev" 59 | description: 60 | name: flutter_lints 61 | sha256: "5398f14efa795ffb7a33e9b6a08798b26a180edac4ad7db3f231e40f82ce11e1" 62 | url: "https://pub.dev" 63 | source: hosted 64 | version: "5.0.0" 65 | flutter_plugin_android_lifecycle: 66 | dependency: transitive 67 | description: 68 | name: flutter_plugin_android_lifecycle 69 | sha256: "9b78450b89f059e96c9ebb355fa6b3df1d6b330436e0b885fb49594c41721398" 70 | url: "https://pub.dev" 71 | source: hosted 72 | version: "2.0.23" 73 | flutter_web_plugins: 74 | dependency: transitive 75 | description: flutter 76 | source: sdk 77 | version: "0.0.0" 78 | google_maps: 79 | dependency: transitive 80 | description: 81 | name: google_maps 82 | sha256: "4d6e199c561ca06792c964fa24b2bac7197bf4b401c2e1d23e345e5f9939f531" 83 | url: "https://pub.dev" 84 | source: hosted 85 | version: "8.1.1" 86 | google_maps_flutter: 87 | dependency: "direct main" 88 | description: 89 | name: google_maps_flutter 90 | sha256: "209856c8e5571626afba7182cf634b2910069dc567954e76ec3e3fb37f5e9db3" 91 | url: "https://pub.dev" 92 | source: hosted 93 | version: "2.10.0" 94 | google_maps_flutter_android: 95 | dependency: transitive 96 | description: 97 | name: google_maps_flutter_android 98 | sha256: a591ff8d0816436e6a4d9f32bbdf10ebb30bb26f72f6db2a51ddb2426ff7d9ec 99 | url: "https://pub.dev" 100 | source: hosted 101 | version: "2.14.8" 102 | google_maps_flutter_ios: 103 | dependency: transitive 104 | description: 105 | name: google_maps_flutter_ios 106 | sha256: "3a484846fc56f15e47e3de1f5ea80a7ff2b31721d2faa88f390f3b3cf580c953" 107 | url: "https://pub.dev" 108 | source: hosted 109 | version: "2.13.0" 110 | google_maps_flutter_platform_interface: 111 | dependency: transitive 112 | description: 113 | name: google_maps_flutter_platform_interface 114 | sha256: a951981c22d790848efb9f114f81794945bc5c06bc566238a419a92f110af6cb 115 | url: "https://pub.dev" 116 | source: hosted 117 | version: "2.9.5" 118 | google_maps_flutter_web: 119 | dependency: transitive 120 | description: 121 | name: google_maps_flutter_web 122 | sha256: ff39211bd25d7fad125d19f757eba85bd154460907cd4d135e07e3d0f98a4130 123 | url: "https://pub.dev" 124 | source: hosted 125 | version: "0.5.10" 126 | html: 127 | dependency: transitive 128 | description: 129 | name: html 130 | sha256: "3a7812d5bcd2894edf53dfaf8cd640876cf6cef50a8f238745c8b8120ea74d3a" 131 | url: "https://pub.dev" 132 | source: hosted 133 | version: "0.15.4" 134 | http_parser: 135 | dependency: transitive 136 | description: 137 | name: http_parser 138 | sha256: "2aa08ce0341cc9b354a498388e30986515406668dbcc4f7c950c3e715496693b" 139 | url: "https://pub.dev" 140 | source: hosted 141 | version: "4.0.2" 142 | lints: 143 | dependency: transitive 144 | description: 145 | name: lints 146 | sha256: "3315600f3fb3b135be672bf4a178c55f274bebe368325ae18462c89ac1e3b413" 147 | url: "https://pub.dev" 148 | source: hosted 149 | version: "5.0.0" 150 | material_color_utilities: 151 | dependency: transitive 152 | description: 153 | name: material_color_utilities 154 | sha256: f7142bb1154231d7ea5f96bc7bde4bda2a0945d2806bb11670e30b850d56bdec 155 | url: "https://pub.dev" 156 | source: hosted 157 | version: "0.11.1" 158 | meta: 159 | dependency: transitive 160 | description: 161 | name: meta 162 | sha256: bdb68674043280c3428e9ec998512fb681678676b3c54e773629ffe74419f8c7 163 | url: "https://pub.dev" 164 | source: hosted 165 | version: "1.15.0" 166 | path: 167 | dependency: transitive 168 | description: 169 | name: path 170 | sha256: "087ce49c3f0dc39180befefc60fdb4acd8f8620e5682fe2476afd0b3688bb4af" 171 | url: "https://pub.dev" 172 | source: hosted 173 | version: "1.9.0" 174 | plugin_platform_interface: 175 | dependency: transitive 176 | description: 177 | name: plugin_platform_interface 178 | sha256: "4820fbfdb9478b1ebae27888254d445073732dae3d6ea81f0b7e06d5dedc3f02" 179 | url: "https://pub.dev" 180 | source: hosted 181 | version: "2.1.8" 182 | sanitize_html: 183 | dependency: transitive 184 | description: 185 | name: sanitize_html 186 | sha256: "12669c4a913688a26555323fb9cec373d8f9fbe091f2d01c40c723b33caa8989" 187 | url: "https://pub.dev" 188 | source: hosted 189 | version: "2.1.0" 190 | sky_engine: 191 | dependency: transitive 192 | description: flutter 193 | source: sdk 194 | version: "0.0.99" 195 | source_span: 196 | dependency: transitive 197 | description: 198 | name: source_span 199 | sha256: "53e943d4206a5e30df338fd4c6e7a077e02254531b138a15aec3bd143c1a8b3c" 200 | url: "https://pub.dev" 201 | source: hosted 202 | version: "1.10.0" 203 | stream_transform: 204 | dependency: transitive 205 | description: 206 | name: stream_transform 207 | sha256: "14a00e794c7c11aa145a170587321aedce29769c08d7f58b1d141da75e3b1c6f" 208 | url: "https://pub.dev" 209 | source: hosted 210 | version: "2.1.0" 211 | string_scanner: 212 | dependency: transitive 213 | description: 214 | name: string_scanner 215 | sha256: "688af5ed3402a4bde5b3a6c15fd768dbf2621a614950b17f04626c431ab3c4c3" 216 | url: "https://pub.dev" 217 | source: hosted 218 | version: "1.3.0" 219 | term_glyph: 220 | dependency: transitive 221 | description: 222 | name: term_glyph 223 | sha256: a29248a84fbb7c79282b40b8c72a1209db169a2e0542bce341da992fe1bc7e84 224 | url: "https://pub.dev" 225 | source: hosted 226 | version: "1.2.1" 227 | typed_data: 228 | dependency: transitive 229 | description: 230 | name: typed_data 231 | sha256: facc8d6582f16042dd49f2463ff1bd6e2c9ef9f3d5da3d9b087e244a7b564b3c 232 | url: "https://pub.dev" 233 | source: hosted 234 | version: "1.3.2" 235 | vector_math: 236 | dependency: transitive 237 | description: 238 | name: vector_math 239 | sha256: "80b3257d1492ce4d091729e3a67a60407d227c27241d6927be0130c98e741803" 240 | url: "https://pub.dev" 241 | source: hosted 242 | version: "2.1.4" 243 | web: 244 | dependency: transitive 245 | description: 246 | name: web 247 | sha256: cd3543bd5798f6ad290ea73d210f423502e71900302dde696f8bff84bf89a1cb 248 | url: "https://pub.dev" 249 | source: hosted 250 | version: "1.1.0" 251 | sdks: 252 | dart: ">=3.5.0 <4.0.0" 253 | flutter: ">=3.24.0" 254 | -------------------------------------------------------------------------------- /pubspec.yaml: -------------------------------------------------------------------------------- 1 | name: google_maps_widget 2 | description: A Flutter package which can be used to make polylines(route) from a source to a destination, and also handle a driver's realtime location (if any) on the map. 3 | version: 1.0.6 4 | homepage: https://github.com/rithik-dev/google_maps_widget 5 | repository: https://github.com/rithik-dev/google_maps_widget 6 | issue_tracker: https://github.com/rithik-dev/google_maps_widget/issues 7 | # documentation: https://github.com/rithik-dev/google_maps_widget/blob/master/README.md 8 | topics: 9 | - flutter 10 | - widget 11 | - google 12 | - google-maps 13 | - google-maps-flutter 14 | 15 | environment: 16 | # constraints from google_maps_flutter and dio dependencies 17 | sdk: ">=3.4.0 <4.0.0" 18 | flutter: ">=3.22.0" 19 | 20 | scripts: 21 | pre_publish: dart format .; flutter pub publish --dry-run 22 | publish_skip_validation: flutter pub publish --skip-validation 23 | publish: flutter pub publish 24 | 25 | dependencies: 26 | flutter: 27 | sdk: flutter 28 | 29 | dio: ^5.7.0 30 | google_maps_flutter: ^2.10.0 31 | 32 | dev_dependencies: 33 | flutter_lints: ^5.0.0 --------------------------------------------------------------------------------