Fork of yandex_mapkit library, but less heavy and more optimized.
Made by Surf ๐ Flutter team ๐
- ๐ Map overview - enables to view the map of the world, with which user can interact with any convinient way, usually in order to demonstrate the location of some place
- ๐ Custom map objects - enables for developers to add custom map objects in order to indicate some place on the map
- ๐ฎ Convinient map controls - there is an API for straight-to-point map controls through the code - from zooming and moving to limiting user scroll and controlling the speed
- ๐ App bundle size reduction - the average bundle size reduction for 25% comparing to projects with original package
- โจ Recommended for use if you don't need anything but basic map
Before you can use MapKit SDK in your application, you need the API key.
-
Go to the Developer Dashboard.
-
Log in to your Yandex account or create a new one.
-
Click Connect APIs and choose MapKit Mobile SDK.
-
Enter information about yourself and your project, select a pricing plan, and click Continue.
-
After your API key is successfully created, it will be available in the API Interfaces โ MapKit Mobile SDK tab.
Add yandex_mapkit_lite
to your pubspec.yaml
file:
dependencies:
yandex_mapkit_lite: $currentVersion$
Specify your API key and locale in ios/Runner/AppDelegate.swift
. It should be similar to the following
import UIKit
import Flutter
import YandexMapsMobile
@UIApplicationMain
@objc class AppDelegate: FlutterAppDelegate {
override func application(
_ application: UIApplication,
didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
) -> Bool {
YMKMapKit.setLocale("YOUR_LOCALE") // Your preferred language. Not required, defaults to system language
YMKMapKit.setApiKey("YOUR_API_KEY") // Your generated API key
GeneratedPluginRegistrant.register(with: self)
return super.application(application, didFinishLaunchingWithOptions: launchOptions)
}
}
Uncomment platform :ios, '9.0'
in ios/Podfile
and change to platform :ios, '12.0'
# Uncomment this line to define a global platform for your project
platform :ios, '12.0'
Add dependency implementation 'com.yandex.android:maps.mobile:4.4.0-lite'
to android/app/build.gradle
dependencies {
implementation 'com.yandex.android:maps.mobile:4.4.0-lite'
}
Specify your API key and locale in your custom application class. If you don't have one the you can create it like so
android/app/src/main/.../MainApplication.java
import android.app.Application;
import com.yandex.mapkit.MapKitFactory;
public class MainApplication extends Application {
@Override
public void onCreate() {
super.onCreate();
MapKitFactory.setLocale("YOUR_LOCALE"); // Your preferred language. Not required, defaults to system language
MapKitFactory.setApiKey("YOUR_API_KEY"); // Your generated API key
}
}
android/app/src/main/.../MainApplication.kt
import android.app.Application
import com.yandex.mapkit.MapKitFactory
class MainApplication: Application() {
override fun onCreate() {
super.onCreate()
MapKitFactory.setLocale("YOUR_LOCALE") // Your preferred language. Not required, defaults to system language
MapKitFactory.setApiKey("YOUR_API_KEY") // Your generated API key
}
}
In your android/app/src/main/AndroidManifest.xml
Add necessary permissions:
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
It is highly recommended to manage map objects in this way due to the performance reasons:
We do not advise you to mix map widget with your screens and other instances - map widget is pretty heavy and can cause huge frame losses.
Additionaly, the map requires some time to warm up and load resources. The recomended way is to make controller nullable, so if there is any interactions with the map, they would be ignored until map is initialized.
If you wish to wait until map is loaded and then do something, consider using Completer
.
class MapWidget extends StatefulWidget {
final List<MapObject> mapObjects;
final MapCreatedCallback? onControllerCreated;
const MapWidget({
required this.mapObjects,
this.onControllerCreated,
Key? key,
}) : super(key: key);
@override
State<MapWidget> createState() => _MapWidgetState();
}
class _MapWidgetState extends State<MapWidget> {
@override
Widget build(BuildContext context) {
return YandexMap(
onMapCreated: widget.onControllerCreated,
mapObjects: widget.mapObjects,
nightModeEnabled: Theme.of(context).brightness == Brightness.dark,
logoAlignment: const MapAlignment(
horizontal: HorizontalAlignment.left,
vertical: VerticalAlignment.top,
),
);
}
}
That's it! Now you can explore the documentation and use map widget for your needs!
However, there are some flaws in this package, they are described in the example
project, and we strongly advise you to consider it.
class MapScreen extends StatefulWidget {
const MapScreen({Key? key}) : super(key: key);
@override
State<MapScreen> createState() => _MapScreenState();
}
class _MapScreenState extends State<MapScreen> {
YandexMapController? _controller;
final _mapObjects = <MapObject>[];
PlacemarkMapObject _buildPlacemark() {
return PlacemarkMapObject(
point: const Point(latitude: 59.945933, longitude: 30.320045),
mapId: const MapObjectId('placemark'),
icon: PlacemarkIcon.single(
PlacemarkIconStyle(
image: BitmapDescriptor.fromAssetImage('assets/place.png'),
),
),
text: PlacemarkText(
text: widget.count.toString(),
style: const PlacemarkTextStyle(
color: Colors.red,
),
),
);
}
@override
void initState() {
_mapObjects.add(_buildPlacemark());
super.initState();
}
@override
void didUpdateWidget(covariant MapScreen oldWidget) {
if (oldWidget.count != widget.count) {
final newPlacemark = _buildPlacemark();
_mapObjects[0] = newPlacemark;
_controller?.moveCamera(
CameraUpdate.newCameraPosition(
CameraPosition(target: newPlacemark.point),
),
);
}
super.didUpdateWidget(oldWidget);
}
...
}
We strongly recommend to get known to the documentation of example project - there is a lot of valuable notes there.
Screen.Recording.2024-02-10.at.20.26.51.mov
There is OS version and platform restrictions for this package. The table for supported platforms and versions of their OS is presented lower:
Android | iOS | |
---|---|---|
Support | SDK 21+ | iOS 12+ |
Mapkit can be used with one language only at the same time.
Due to native constraints after the application is launched language can't be changed.
By default android views are rendered using Hybrid Composition. In order to render the YandexMap
widget on Android using Virtual Display (old composition), set [AndroidYandexMap.useAndroidViewSurface] to false before using YandexMap
widget.
AndroidYandexMap.useAndroidViewSurface = false;