MapView

API Reference: UI.MapView

MapView is a view to display native maps (Apple Maps on iOS and Google Maps on Android).

Android Manifest

Smartface Android Emulator comes with its own Google Maps API-Keys. Before publishing your project, you must change that key from AndroidManifest.xml. Follow the guide to get a key.

Updating AndroidManifest.xml

  • Go to /config/Android/AndroidManifest.xml

  • Add the following code below under tag

AndroidManifest.xml
AndroidManifest.xml
<meta-data
android:name="com.google.android.geo.API_KEY"
android:value=" ADD API-KEY HERE "
/>

Basic MapView

In this example, lazy loading is also enabled on Line 73. Note that this is Android only property. For more information please refer here.

TypeScript
TypeScript
import PageSampleDesign from 'generated/pages/pageSample';
import FlexLayout from 'sf-core/ui/flexlayout';
import Application from 'sf-core/application';
import MapView from 'sf-core/ui/mapview';
import Color from 'sf-core/ui/color';
//You should create new Page from UI-Editor and extend with it.
export default class Sample extends PageSampleDesign {
myMapView: MapView;
constructor() {
super();
this.onShow = onShow.bind(this, this.onShow.bind(this));
this.onLoad = onLoad.bind(this, this.onLoad.bind(this));
this.layout.flexDirection = FlexLayout.FlexDirection.ROW;
this.layout.justifyContent = FlexLayout.JustifyContent.CENTER;
this.layout.alignItems = FlexLayout.AlignItems.CENTER;
}
initMapView() {
this.myMapView = new MapView({
scrollEnabled: true,
rotateEnabled: true,
zoomEnabled: true,
compassEnabled: true,
type: MapView.Type.NORMAL,
onCreate: (): void => {
const centerLocation = {
latitude: 37.4488259,
longitude: -122.1600047
};
this.myMapView.setCenterLocationWithZoomLevel(centerLocation, 11, false);
for (let i = 0; i < 10; i++) {
const myPin = new MapView.Pin({
location: {
latitude: 37.4488259 + i * 0.01,
longitude: -122.1600047
},
title: 'Title ' + i,
subtitle: 'Subtitle',
color: Color.RED
});
myPin.onPress = (index: number) => {
console.log("Title : " + myPin.index);
};
this.myMapView.addPin(myPin);
}
}
});
this.layout.addChild(this.myMapView, "myMapView", ".sf-mapView", {
height: null,
left: 0,
top: 0,
right: 0,
bottom: 0,
flexProps: {
positionType: "ABSOLUTE"
}
});
}
}
function onShow(superOnShow: () => void) {
const { headerBar } = this;
superOnShow();
Application.statusBar.visible = false;
headerBar.visible = false;
// Enable lazy loading on Android
this.myMapView.android.prepareMap();
}
function onLoad(superOnLoad: () => void) {
superOnLoad();
this.initMapView();
}

MapView with Cluster

Cluster that groups two or more distinct pins into a single entity. Cluster works on Android & iOS 11.0+.

Page
Page
import PageSampleDesign from 'generated/pages/pageSample';
import FlexLayout from 'sf-core/ui/flexlayout';
import Application from 'sf-core/application';
import MapView from 'sf-core/ui/mapview';
import Color from 'sf-core/ui/color';
import Font from 'sf-core/ui/font';
type locationType = { latitude: number, longitude: number };
//You should create new Page from UI-Editor and extend with it.
export default class Sample extends PageSampleDesign {
myMapView: MapView;
constructor() {
super();
this.onShow = onShow.bind(this, this.onShow.bind(this));
this.onLoad = onLoad.bind(this, this.onLoad.bind(this));
this.layout.flexDirection = FlexLayout.FlexDirection.ROW;
this.layout.justifyContent = FlexLayout.JustifyContent.CENTER;
this.layout.alignItems = FlexLayout.AlignItems.CENTER;
}
averageGeolocation(pins: MapView.Pin[]): locationType {
if (pins.length === 1) {
return pins[0].location;
}
let x = 0.0;
let y = 0.0;
let z = 0.0;
pins.forEach((pin) => {
let latitude = pin.location.latitude * Math.PI / 180;
let longitude = pin.location.longitude * Math.PI / 180;
x += Math.cos(latitude) * Math.cos(longitude);
y += Math.cos(latitude) * Math.sin(longitude);
z += Math.sin(latitude);
});
const total = pins.length;
x = x / total;
y = y / total;
z = z / total;
const centralLongitude = Math.atan2(y, x);
const centralSquareRoot = Math.sqrt(x * x + y * y);
const centralLatitude = Math.atan2(z, centralSquareRoot);
return {
latitude: centralLatitude * 180 / Math.PI,
longitude: centralLongitude * 180 / Math.PI
};
}
initMapView() {
this.myMapView = new MapView({
flexGrow: 1,
onCreate: () => {
const centerLocation = {
latitude: 37.4488259,
longitude: -122.1600047
};
this.myMapView.setCenterLocationWithZoomLevel(centerLocation, 12, false);
for (let i = 0; i < 10; i++) {
const myPin = new MapView.Pin({
location: {
latitude: 37.4488259 + i * 0.01,
longitude: -122.1600047
},
title: 'Title ' + i,
//@ts-ignore
subtitle: 'Subtitle',
color: Color.RED
});
myPin.onPress = () => {
console.info("Title : ", myPin.title);
};
this.myMapView.addPin(myPin);
}
}
});
this.myMapView.clusterEnabled = true;
this.myMapView.clusterFillColor = Color.RED;
this.myMapView.clusterBorderColor = Color.WHITE;
this.myMapView.ios.clusterBorderWidth = 3;
this.myMapView.clusterTextColor = Color.WHITE;
this.myMapView.clusterFont = Font.create(Font.DEFAULT, 20, Font.BOLD);
this.myMapView.ios.clusterPadding = 15;
//@ts-ignore
this.myMapView.onClusterPress = (pins: MapView.Pin[]) => {
var centerLocation = this.averageGeolocation(pins);
this.myMapView.setCenterLocationWithZoomLevel(centerLocation, 12, true);
};
//@ts-ignore
this.layout.addChild(this.myMapView, "myMapView", ".sf-mapView", {
height: null,
left: 0,
top: 0,
right: 0,
bottom: 0,
flexProps: {
positionType: "ABSOLUTE"
}
});
}
}
function onShow(superOnShow: () => void) {
superOnShow();
Application.statusBar.visible = false;
this.headerBar.visible = false;
// Enable lazy loading on Android
this.myMapView.android.prepareMap();
}
function onLoad(superOnLoad: () => void) {
superOnLoad();
this.initMapView();
}

d

Removing all pins at once

Developers don't need to store all pins remove them later.

This can be handled by calling myMap.removeAllPins();

Adding pins

Pins must be added after onCreate event is triggered.