Dokumentation / Kartenansicht / MapView und Zustand

MapView-Lebenszyklus und Ereignisse

Die Karte wird mit zwei Objekten behandelt: der Ansicht und dem Zustandsobjekt. Der Zustand (mapViewState) ist die Schnittstelle für Kamera, Design und Interaktion, während die Ansicht nur im UI-Baum der jeweiligen Plattform platziert wird. Die Initialisierung läuft durch gemeinsame Phasen, und das Laden abgeschlossen sowie Benutzeraktionen werden über Ereignisse empfangen.

ANDROID
MapViewStateInterface
iOS
MapViewStateProtocol
REACT
MapViewStateInterface
Plattform

01 · mapViewState

mapViewState ist ein Zustandsobjekt, das einer einzelnen Kartenfläche entspricht. Es gibt implementierungsspezifische Versionen pro Anbieter, aber die öffentlich zugänglichen Member sind gemeinsam; Anwendungscode muss nur die gemeinsame Schnittstelle beachten.

Der Zustand lebt länger als die Ansicht. Selbst wenn die Ansicht neu erstellt wird, verbleiben Kameraposition und Design auf der Zustandsseite, sodass die Karte unverändert wiederhergestellt wird.

Member
Beschreibung
id
Der Bezeichner des Zustands. Er verweist über die Neuerstellung der Ansicht hinweg auf dieselbe Karte.
cameraPosition
Die aktuelle Kameraposition. Der sichtbare Bereich (visibleRegion) kann auch hieraus abgerufen werden.
mapDesignType
Das aktuelle Kartendesign. Bei Zuweisung wird sofort umgeschaltet.
moveCameraTo()
Verschiebt die Kamera. Wenn eine Zeitdauer übergeben wird, wird sie animiert.
fitBounds()
Richtet die Kamera so aus, dass der angegebene Bereich hineinpasst. Auf allen drei Plattformen als Methode des Zustandsobjekts implementiert, delegiert intern an einen Controller.
getMapViewHolder()
Gibt einen Halter zurück, der die native Karteninstanz umschließt.
MapViewState · Jetpack Compose
// Den State mit remember* erzeugen, damit dieselbe Karte eine Drehung übersteht
val mapViewState =
    rememberGoogleMapViewState(
        mapDesign = GoogleMapDesign.Normal,
        cameraPosition = initCameraPosition,
    )

GoogleMapView(state = mapViewState, modifier = Modifier.fillMaxSize())

02 · Initialisierungslebenszyklus

Die Karteninitialisierung durchläuft auf allen Anbietern dieselben Phasen: Laden des SDK, Erzeugen der Ansicht, Erzeugen der Karteninstanz und Abschluss des Kachelns. Da die Phasen als InitState gemeinsam sind, müssen Sie nicht anbieterspezifisch merken, wann noch nicht interagiert werden darf.

Kamerabewegungen und das Hinzufügen von Overlays werden ab MapCreated akzeptiert und intern in eine Warteschlange gestellt. Wenn Sie erst nach Abschluss des Ladens etwas tun möchten, verwenden Sie onMapLoaded.

Abbildung · wie InitState fortschreitet
NotStarted
Es hat noch nichts begonnen.
Initializing
Die Initialisierung beginnt — Schlüsselprüfung und Laden des SDK.
SdkInitialized
Das Karten-SDK selbst ist fertig geladen.
MapViewCreated
Die Plattform-View (MapView / UIView / DOM-Element) ist erzeugt.
MapCreating
Die Karteninstanz wird in der View erzeugt.
MapCreated
Die Karteninstanz ist nutzbar; Kamerabewegungen und Overlays greifen ab jetzt.
MapLoaded
Die Kacheln sind gezeichnet. In dieser Phase wird onMapLoaded ausgelöst.
Failed
Die Initialisierung ist fehlgeschlagen — falscher Schlüssel, kein Netz und Ähnliches.
Die Stufen sind auf Android, iOS und React als dieselbe Aufzählung deklariert; worauf Sie warten, ändert sich beim Wechsel des Anbieters also nicht.
01 sdkInitialize

Lädt das Karten-SDK. Im Web per Skriptinjektion, auf Mobilgeräten per Initialisierung. Im Fehlerfall wird zu Failed gewechselt.

02 createHolder

Umschließt die native Karteninstanz mit einem Holder. Ab hier sind SDK-spezifische Typen verborgen.

03 createController

Umschließt den Holder mit einem Controller und stellt die gemeinsame API sowie die Event-Verdrahtung bereit. Der Controller wird mit dem Zustand verbunden.

RESTORE

Über Bildschirmrotation und Neuerstellung hinweg

Unter Android wird der Zustand mit rememberSaveable gespeichert; nach einer Bildschirmrotation oder Konfigurationsänderung werden Kameraposition und Design wiederhergestellt. Bei Konfigurationsänderungen wird die Kartenansicht selbst nicht zerstört, sondern wiederverwendet.

TEARDOWN

Wenn zerstört

Bei einer echten Zerstörung (Verlassen des Bildschirms) werden das Overlay-Management, die Routen des Kachel-Servers und der Coroutine-Scope, die der Controller hält, gemeinsam freigegeben. Auch beim Wechsel des Anbieters wird die alte Karte über denselben Pfad bereinigt.

Implementierung im Video · Android + MapLibreKotlin · Jetpack Compose
var ready by remember { mutableStateOf(false) }

MapLibreMapView(
    state = mapViewState,
    // Called once, when the tiles have finished drawing
    onMapLoaded = { state ->
        ready = true
        state.fitBounds(routeBounds, padding = 48)
    },
) {
    // Declarations here are not lost before MapCreated — they are queued internally
    Marker(markerState)
}

if (!ready) {
    // Your own loading overlay, if you want one. The map does not need blocking
    Box(Modifier.fillMaxSize()) { CircularProgressIndicator() }
}
Beispielvideo · Fortschritt der Initialisierung
Video noch nicht aufgenommenWie InitState stufenweise fortschreitet, nachdem die Karte erzeugt wurde, bis sie Interaktionen akzeptiert. Der Zeitpunkt des Wechsels von der Ladeanzeige ist gut erkennbar.

03 · Ereignisse

Die Handler, die an die Ansicht übergeben werden, haben auf allen drei Plattformen dieselbe Struktur. Die Typen sind ebenfalls gemeinsam: Laden abgeschlossen empfängt das Zustandsobjekt, Tippen empfängt Koordinaten, Kameraänderung empfängt die Kameraposition.

Ereignis
Empfangener Wert
Beschreibung
onMapLoaded
MapViewState
Laden der Karte abgeschlossen. Es ist üblich, das Statusobjekt aus dem Argument zu speichern und für nachfolgende Vorgänge zu verwenden.
onMapClick
GeoPoint
Tippen auf die Karte. Zum Schließen von Informationsblasen, Setzen von Pins usw.
onMapLongClick
GeoPoint
Langes Drücken.
onCameraMoveStart
MapCameraPosition
Beginn der Kamerasteuerung. W sowohl bei Benutzerinteraktion als auch bei programmatischer Bewegung aufgerufen.
onCameraMove
MapCameraPosition
Wird während der Bewegung fortlaufend aufgerufen. Für die Anzeige von Koordinaten usw.
onCameraMoveEnd
MapCameraPosition
Wenn die Bewegung stoppt. Das erneute Abrufen von Daten sollte grundsätzlich hier durchgeführt werden.
GoogleMapView · Empfang von Ereignissen
GoogleMapView(
    state = mapViewState,
    onMapLoaded = { state -> viewModel.onMapLoaded(state) },
    onMapClick = { point -> viewModel.onMapClick(point) },
    onCameraMove = { camera -> viewModel.onCameraChanged(camera) },
    onCameraMoveEnd = { camera -> viewModel.onCameraSettled(camera) },
) { /* markers, overlays */ }

Kamera-bezogene Ereignisse aktualisieren gleichzeitig cameraPosition des Statusobjekts, sodass die neueste Kamera immer gelesen werden kann, auch ohne Handler. Wenn Sie ein erneutes Abrufen während der Bewegung vermeiden möchten, verwenden Sie nur onCameraMoveEnd.

04 · Ausweg zu Native

Für den Fall, dass die gemeinsame API nicht ausreicht, haben wir eine Möglichkeit vorbereitet, auf die native Karteninstanz zuzugreifen. Normalerweise wird sie nicht verwendet, dient aber als Ausweg, wenn Sie eine anbieterspezifische Funktion nur an einer Stelle verwenden möchten.

MapViewHolder

Holder, der die native Karte umschließt

Der Holder besitzt zwei Elemente: die Plattform-Ansicht und die Karteninstanz. SDK-spezifischer Code wird ab hier isoliert und nicht an den gemeinsamen Code durchgelassen.

toScreenOffset / fromScreenOffset

Umrechnung zwischen Koordinaten und Bildschirmposition

Geografische Koordinaten und Pixelpositionen auf dem Bildschirm können gegenseitig umgerechnet werden. Dies wird verwendet, wenn eine benutzerdefinierte UI über die Karte gelegt wird.

Abrufen des Holders
// Nur herausholen, wenn Sie die native API wirklich brauchen
val holder = mapViewState.getMapViewHolder()
val nativeMap = holder?.map // GoogleMap / MapLibreMap / ...
val offset = holder?.toScreenOffset(point)

Code, der den Holder verwendet, hängt vom Anbieter ab. Bitte trennen Sie bewusst die Teile, die Sie gemeinschaftlich halten möchten, von den Teilen, für die Sie gezielt eine spezifische API verwenden.

Verwandte Seiten