React Native Map-Komponenten für iOS + Android
Dieses Projekt wird von einer kleinen Gruppe von Leuten betreut und jede Hilfe bei Problemen und Pull-Anfragen ist jederzeit willkommen. Wenn Sie in der Lage und bereit sind, einen Beitrag zu leisten, lesen Sie bitte die Richtlinien.
Siehe Installationsanweisungen.
Siehe Setup-Anweisungen für das mitgelieferte Beispielprojekt.
react-native >= 0.74
.react-native >= 0.64.3
erforderlich. <MapView />
Komponenten-API
<Marker />
Komponenten-API
<Callout />
Komponenten-API
<Polygon />
Komponenten-API
<Polyline />
Komponenten-API
<Circle />
Komponenten-API
<Overlay />
Komponenten-API
<Heatmap />
Komponenten-API
<Geojson />
Komponenten-API
import MapView from 'react-native-maps' ;
oder
var MapView = require ( 'react-native-maps' ) ;
Diese MapView-Komponente ist so aufgebaut, dass Features auf der Karte (z. B. Markierungen, Polygone usw.) als untergeordnete Elemente der MapView selbst angegeben werden. Dies bietet eine intuitive und reaktionsähnliche API zur deklarativen Steuerung von Features auf der Karte.
< MapView
initialRegion = { {
latitude : 37.78825 ,
longitude : - 122.4324 ,
latitudeDelta : 0.0922 ,
longitudeDelta : 0.0421 ,
} }
/ >
getInitialState ( ) {
return {
region : {
latitude : 37.78825 ,
longitude : - 122.4324 ,
latitudeDelta : 0.0922 ,
longitudeDelta : 0.0421 ,
} ,
} ;
}
onRegionChange ( region ) {
this . setState ( { region } ) ;
}
render ( ) {
return (
< MapView
region = { this . state . region }
onRegionChange = { this . onRegionChange }
/ >
) ;
}
import { Marker } from 'react-native-maps' ;
< MapView region = { this . state . region } onRegionChange = { this . onRegionChange } >
{ this . state . markers . map ( ( marker , index ) => (
< Marker
key = { index }
coordinate = { marker . latlng }
title = { marker . title }
description = { marker . description }
/ >
) ) }
< / MapView > ;
png
Bild mit unterschiedlicher Auflösung generieren (nennen wir sie custom_pin
) – weitere Informationen finden Sie unter Android, iOS < Marker
coordinate = { { latitude : latitude , longitude : longitude } }
image = { { uri : 'custom_pin' } }
/ >
Hinweis: Sie können die Bildbinärdaten auch wie image={require('custom_pin.png')}
übergeben, dies lässt sich jedoch nicht gut an die verschiedenen Bildschirmgrößen anpassen.
Hinweis: Dies hat Auswirkungen auf die Leistung. Wenn Sie eine einfachere Lösung wünschen, verwenden Sie ein benutzerdefiniertes Bild (ersparen Sie sich die Kopfschmerzen).
< Marker coordinate = { { latitude : latitude , longitude : longitude } } >
< MyCustomMarkerView { ... marker } / >
< / Marker >
import { Callout } from 'react-native-maps' ;
< Marker coordinate = { marker . latlng } >
< MyCustomMarkerView { ... marker } / >
< Callout >
< MyCustomCalloutView { ... marker } / >
< / Callout >
< / Marker > ;
< MapView initialRegion = { ... } >
< Marker draggable
coordinate = { this . state . x }
onDragEnd = { ( e ) => this . setState ( { x : e . nativeEvent . coordinate } ) }
/ >
< / MapView >
import { UrlTile } from 'react-native-maps' ;
< MapView region = { this . state . region } onRegionChange = { this . onRegionChange } >
< UrlTile
/**
* The url template of the tile server. The patterns {x} {y} {z} will be replaced at runtime
* For example, http://c.tile.openstreetmap.org/{z}/{x}/{y}.png
*/
urlTemplate = { this . state . urlTemplate }
/**
* The maximum zoom level for this tile overlay. Corresponds to the maximumZ setting in
* MKTileOverlay. iOS only.
*/
maximumZ = { 19 }
/**
* flipY allows tiles with inverted y coordinates (origin at bottom left of map)
* to be used. Its default value is false.
*/
flipY = { false }
/ >
< / MapView > ;
Für Android: Fügen Sie die folgende Zeile in Ihre AndroidManifest.xml ein
< uses-permission android : name = " android.permission.INTERNET " />
Für IOS: Konfigurieren Sie App Transport Security in Ihrer App
Diese Bibliothek funktioniert mit Fabric unter Verwendung der neuen Renderer-Interop-Ebene
Es wird eine Warnmeldung angezeigt, dass diese Schritte nicht erforderlich sind. Aber ohne sie konnten wir das Beispiel bisher nicht zum Laufen bringen.
Öffnen Sie Ihre Konfigurationsdatei : Suchen Sie die Datei react-native-config
in Ihrem Projektverzeichnis.
Fügen Sie die folgende Konfiguration hinzu : Fügen Sie das Array unstable_reactLegacyComponentNames
sowohl für Android- als auch für iOS-Plattformen ein, wie unten gezeigt:
module . exports = {
project : {
android : {
unstable_reactLegacyComponentNames : [
'AIRMap' ,
'AIRMapCallout' ,
'AIRMapCalloutSubview' ,
'AIRMapCircle' ,
'AIRMapHeatmap' ,
'AIRMapLocalTile' ,
'AIRMapMarker' ,
'AIRMapOverlay' ,
'AIRMapPolygon' ,
'AIRMapPolyline' ,
'AIRMapUrlTile' ,
'AIRMapWMSTile' ,
] ,
} ,
ios : {
unstable_reactLegacyComponentNames : [
'AIRMap' ,
'AIRMapCallout' ,
'AIRMapCalloutSubview' ,
'AIRMapCircle' ,
'AIRMapHeatmap' ,
'AIRMapLocalTile' ,
'AIRMapMarker' ,
'AIRMapOverlay' ,
'AIRMapPolygon' ,
'AIRMapPolyline' ,
'AIRMapUrlTile' ,
'AIRMapWMSTile' ,
] ,
} ,
} ,
} ;
Schauen Sie sich das Beispielprojekt an, um es in Aktion zu sehen.
Kacheln können mithilfe des xyz-Kachelschemas lokal im Gerät gespeichert und auch als Kachel-Overlay angezeigt werden. Dies ist insbesondere für die Offline-Kartennutzung nützlich, wenn Kacheln für ausgewählte Kartenregionen im Gerätespeicher verfügbar sind.
import { LocalTile } from 'react-native-maps' ;
< MapView region = { this . state . region } onRegionChange = { this . onRegionChange } >
< LocalTile
/**
* The path template of the locally stored tiles. The patterns {x} {y} {z} will be replaced at runtime
* For example, /storage/emulated/0/mytiles/{z}/{x}/{y}.png
*/
pathTemplate = { this . state . pathTemplate }
/**
* The size of provided local tiles (usually 256 or 512).
*/
tileSize = { 256 }
/ >
< / MapView > ;
Für Android: LocalTile wird immer noch nur über die ursprünglichen Kartenkacheln gelegt. Das bedeutet, dass die zugrunde liegenden Kacheln trotzdem heruntergeladen werden, wenn das Gerät online ist. Wenn das Herunterladen/Anzeigen der Originalkacheln nicht erwünscht ist, setzen Sie „mapType“ auf „none“. Zum Beispiel:
<MapView
mapType={Platform.OS == "android" ? "none" : "standard"}
>
Informationen zum Herunterladen von Kacheln für die Offline-Nutzung finden Sie im OSM-Wiki.
Platzieren Sie Komponenten, die Sie MapView
überlagern möchten, unter dem schließenden Tag MapView
. Positionieren Sie diese Elemente unbedingt.
render ( ) {
return (
< MapView
region = { this . state . region }
/ >
< OverlayComponent
style = { { position : "absolute" , bottom : 50 } }
/ >
) ;
}
Der <MapView provider="google" googleMapId="yourStyledMapId" />
Google Maps auf iOS und Android unterstützt das Styling über die Google Cloud-Plattform. Die gestalteten Karten werden unter einer googleMapId veröffentlicht. Durch einfaches Festlegen der Eigenschaft googleMapId auf MapView können Sie diese verwenden Weitere Informationen zur gestalteten Karte finden Sie hier: Google Map-ID
Die <MapView />
Komponente und ihre untergeordneten Komponenten verfügen über mehrere Ereignisse, die Sie abonnieren können. In diesem Beispiel werden einige davon als Demonstration in einem Protokoll angezeigt.
Man kann die Position der Kartenansicht mithilfe von Refs und Komponentenmethoden oder durch Übergabe einer aktualisierten region
ändern. Die Komponentenmethoden ermöglichen es, wie mit der nativen API zu einer bestimmten Position zu animieren.
Die <MapView />
Komponente kann mit der Animated API zusammenarbeiten, indem die gesamte region
als animierter Wert deklariert wird. Dies ermöglicht es, den Zoom und die Position der Kartenansicht zusammen mit anderen Gesten zu animieren, was ein angenehmes Gefühl vermittelt.
Darüber hinaus können Marker-Ansichten die animierte API nutzen, um den Effekt zu verstärken.
Problem: Da Android seine Markierungsansichten als Bitmap rendern muss, sind die Animations-APIs möglicherweise nicht mit den Markierungsansichten kompatibel. Ich bin mir nicht sicher, ob dies bereits umgangen werden kann oder nicht.
Die Koordinaten von Markierungen können auch animiert werden, wie in diesem Beispiel gezeigt:
Bisher stehen <Circle />
, <Polygon />
und <Polyline />
zur Übergabe als untergeordnete Elemente an die <MapView />
Komponente zur Verfügung.
Verlaufspolylinien können mit der strokeColors
-Requisite der <Polyline>
-Komponente erstellt werden.
Standardmarkierungen werden gerendert, sofern keine benutzerdefinierte Markierung angegeben wird. Optional kann die Farbe des Standardmarkers mithilfe der pinColor
Requisite angepasst werden.
Callouts zu Markierungen können völlig beliebige Reaktionsansichten sein, ähnlich wie Markierungen. Dadurch kann mit ihnen wie mit jeder anderen Ansicht interagiert werden.
Darüber hinaus können Sie über die title
und description
Requisiten von <Marker />
auf das Standardverhalten zurückgreifen, bei dem nur ein Titel/eine Beschreibung vorhanden ist.
Benutzerdefinierte Callout-Ansichten können die gesamte Tooltip-Blase oder nur den Inhalt innerhalb der Standard-Blase des Systems umfassen.
Um das Drücken einer bestimmten Unteransicht des Callouts zu verarbeiten, verwenden Sie <CalloutSubview />
mit onPress
. Siehe Callouts.js
-Beispiel.
Markierungen können einfach durch die Verwendung von Bildern angepasst und mithilfe der image
Requisite angegeben werden.
Markierungen sind ziehbar und geben kontinuierliche Ziehereignisse aus, um andere Benutzeroberflächen während des Ziehens zu aktualisieren.
Aktivieren Sie den Lite-Modus auf Android mit liteMode
Prop. Ideal, wenn mehrere Karten in einer Ansicht oder ScrollView vorhanden sind.
Poi sind anklickbar. Sie können das Ereignis abfangen, um dessen Informationen abzurufen (normalerweise, um mithilfe der placeId die vollständigen Details von Google Place abzurufen).
Die MapView kann einen AnimatedRegion
Wert als region
akzeptieren. Dadurch können Sie die Animated API verwenden, um die Mitte und den Zoom der Karte zu steuern.
import MapView , { AnimatedRegion , Animated } from 'react-native-maps' ;
getInitialState ( ) {
return {
region : new AnimatedRegion ( {
latitude : LATITUDE ,
longitude : LONGITUDE ,
latitudeDelta : LATITUDE_DELTA ,
longitudeDelta : LONGITUDE_DELTA ,
} ) ,
} ;
}
onRegionChange ( region ) {
this . state . region . setValue ( region ) ;
}
render ( ) {
return (
< Animated
region = { this . state . region }
onRegionChange = { this . onRegionChange }
/ >
) ;
}
Markierungen können auch einen AnimatedRegion
Wert als Koordinate akzeptieren.
import MapView , { AnimatedRegion , MarkerAnimated } from 'react-native-maps' ;
getInitialState ( ) {
return {
coordinate : new AnimatedRegion ( {
latitude : LATITUDE ,
longitude : LONGITUDE ,
} ) ,
} ;
}
componentWillReceiveProps ( nextProps ) {
const duration = 500
if ( this . props . coordinate !== nextProps . coordinate ) {
if ( Platform . OS === 'android' ) {
if ( this . marker ) {
this . marker . animateMarkerToCoordinate (
nextProps . coordinate ,
duration
) ;
}
} else {
this . state . coordinate . timing ( {
... nextProps . coordinate ,
useNativeDriver : true , // defaults to false if not passed explicitly
duration
} ) . start ( ) ;
}
}
}
render ( ) {
return (
< MapView initialRegion = { ... } >
< MarkerAnimated
ref = { marker => { this . marker = marker } }
coordinate = { this . state . coordinate }
/ >
< / MapView >
) ;
}
import MapView , { Marker } from 'react-native-maps' ;
getInitialState ( ) {
return {
coordinate : {
latitude : LATITUDE ,
longitude : LONGITUDE ,
} ,
} ;
}
takeSnapshot ( ) {
// 'takeSnapshot' takes a config object with the
// following options
const snapshot = this . map . takeSnapshot ( {
width : 300 , // optional, when omitted the view-width is used
height : 300 , // optional, when omitted the view-height is used
region : { . . } , // iOS only, optional region to render
format : 'png' , // image formats: 'png', 'jpg' (default: 'png')
quality : 0.8 , // image quality: 0..1 (only relevant for jpg, default: 1)
result : 'file' // result types: 'file', 'base64' (default: 'file')
} ) ;
snapshot . then ( ( uri ) => {
this . setState ( { mapSnapshot : uri } ) ;
} ) ;
}
render ( ) {
return (
< View >
< MapView initialRegion = { ... } ref = { map => { this . map = map } } >
< Marker coordinate = { this . state . coordinate } / >
< / MapView >
< Image source = { { uri : this . state . mapSnapshot . uri } } / >
< TouchableOpacity onPress = { this . takeSnapshot } >
Take Snapshot
< / TouchableOpacity >
< / View >
) ;
}
Übergeben Sie ein Array von Markierungsbezeichnern, damit die Karte neu fokussiert wird.
Übergeben Sie ein Koordinatenarray, um einen Kartenbereich auf diese Koordinaten zu fokussieren.
const styles = StyleSheet . create ( {
map : {
... StyleSheet . absoluteFillObject ,
} ,
} ) ;
< MapView
style = { styles . map }
// other props
/ >
Schlecht:
< View >
< TextInput / >
< MapView / >
< / View >
Gut:
< View >
< MapView / >
< TextInput / >
< / View >
Komponenten, die nicht von dieser Bibliothek deklariert werden (z. B. Markierungen, Polylinien), dürfen aufgrund der einzigartigen Rendering-Methode von MapView keine untergeordneten Elemente der MapView-Komponente sein. Platzieren Sie Ihre benutzerdefinierten Komponenten/Ansichten außerhalb der MapView-Komponente und positionieren Sie sie absolut, um sicherzustellen, dass sie nur bei Bedarf erneut gerendert werden. Beispiel: Schlecht:
< View style = { StyleSheet . absoluteFillObject } >
< MapView style = { StyleSheet . absoluteFillObject } >
< View style = { { position : 'absolute' , top : 100 , left : 50 } } / >
< / MapView >
< / View >
Gut:
< View style = { StyleSheet . absoluteFillObject } >
< MapView style = { StyleSheet . absoluteFillObject } / >
< View style = { { position : 'absolute' , top : 100 , left : 50 } } / >
< / View >
Quelle: #1901
<MapView>
das Apple Maps in mapType: "standard"
verwendet, stürzt manchmal ab, wenn Sie die App im Hintergrund ausführen oder zu einer anderen App wechseln. Dies ist nur ein Problem in XCode, das die Metal-API-Validierung verwendet, und tritt in der Produktion nicht auf. Um dieses Problem auch beim Debuggen in XCode zu beseitigen, gehen Sie zu Edit Scheme... -> Run (Debug) -> Diagnostics
und deaktivieren Sie Metal -> API Validation
. (h/t @Simon-TechForm).
Quelle: #3957 (Kommentar)
Wenn die Änderung des Status in onRegionChangeComplete
unbegrenzt aufgerufen wird, fügen Sie eine Bedingung hinzu, um diese Aufrufe so zu beschränken, dass sie nur dann erfolgen, wenn die Regionsänderung als Ergebnis einer Benutzeraktion durchgeführt wurde.
onRegionChangeComplete = { ( region , gesture ) => {
// This fix only works on Google Maps because isGesture is NOT available on Apple Maps
if ( ! gesture . isGesture ) {
return ;
}
// You can use
dispatch ( { type : "map_region" , payload : { mapRegion : region }