Documentación / Vista de mapa / MapView y estado

Ciclo de vida y eventos de MapView

El mapa se maneja con dos objetos: la vista y el objeto de estado. El estado (mapViewState) es la interfaz para la cámara, el diseño y la manipulación, y la vista simplemente se coloca en el árbol de UI de cada plataforma. La inicialización sigue etapas comunes, y la carga finalizada y las acciones del usuario se reciben como eventos.

ANDROID
MapViewStateInterface
iOS
MapViewStateProtocol
REACT
MapViewStateInterface
Plataforma

01 · mapViewState

mapViewState es un objeto de estado que corresponde a una cara del mapa. Hay implementaciones por proveedor, pero los miembros públicos son comunes; el código de la aplicación solo necesita mirar la interfaz común.

El estado vive más tiempo que la vista. Incluso si se vuelve a crear la vista, la posición de la cámara y el diseño permanecen en el lado del estado, por lo que el mapa se restaura tal como estaba.

Miembros
Descripción
id
El identificador del estado. Sigue apuntando al mismo mapa a través de la regeneración de la vista.
cameraPosition
La posición actual de la cámara. El área visible (visibleRegion) también se puede obtener desde aquí.
mapDesignType
El diseño de mapa actual. Al asignarlo, cambia de inmediato.
moveCameraTo()
Mueve la cámara. Si se pasa una duración, se anima.
fitBounds()
Ajusta la cámara para que quepa el rango especificado. En las tres plataformas es un método del objeto de estado y delega internamente a un controlador.
getMapViewHolder()
Devuelve un contenedor que envuelve la instancia de mapa nativa.
MapViewState · Jetpack Compose
// Crea el estado con remember*, así el mismo mapa sobrevive a una rotación
val mapViewState =
    rememberGoogleMapViewState(
        mapDesign = GoogleMapDesign.Normal,
        cameraPosition = initCameraPosition,
    )

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

02 · Ciclo de vida de inicialización

La inicialización del mapa sigue las mismas etapas en todos los proveedores: carga del SDK, generación de la vista, generación de la instancia de mapa y finalización del dibujo de mosaicos. Como las etapas están comúnizadas como InitState, no necesita recordar por proveedor cuándo aún no se debe manipular.

Las manipulaciones de cámara y adiciones de superposiciones se aceptan a partir de MapCreated y se ponen en cola internamente. Si desea hacer algo después de que la carga haya finalizado, use onMapLoaded.

Figura · cómo avanza InitState
NotStarted
Todavía no ha empezado nada.
Initializing
Comienza la inicialización: validación de la clave y carga del SDK.
SdkInitialized
El SDK de mapas ha terminado de cargarse.
MapViewCreated
Se crea la vista de la plataforma (MapView / UIView / elemento DOM).
MapCreating
Se está creando la instancia del mapa dentro de la vista.
MapCreated
La instancia del mapa ya se puede usar; los movimientos de cámara y las capas empiezan a aplicarse.
MapLoaded
Las teselas están dibujadas. onMapLoaded se dispara en esta etapa.
Failed
La inicialización falló: clave incorrecta, sin red, etc.
Las etapas se declaran como la misma enumeración en Android, iOS y React, así que lo que hay que esperar no cambia al cambiar de proveedor.
01 sdkInitialize

Carga el SDK del mapa. En la Web mediante inyección de scripts, en dispositivos móviles mediante proceso de inicialización. Si falla, pasa a Failed.

02 createHolder

Envuelve la instancia de mapa nativa con un holder. A partir de aquí, los tipos específicos del SDK quedan ocultos.

03 createController

Envuelve el holder con un controlador y prepara la API común y el cableado de eventos. El controlador se conecta al estado.

RESTORE

A través de la rotación de pantalla y regeneración

En Android, el estado se guarda con rememberSaveable; después de una rotación de pantalla o cambio de configuración, se restauran la posición de la cámara y el diseño. En los cambios de configuración, la vista del mapa en sí no se destruye, sino que se reutiliza.

TEARDOWN

Cuando se destruye

En una destrucción real (salida de la pantalla), se liberan conjuntamente la gestión de superposiciones, las rutas del servidor de mosaicos y el alcance de las corrutinas que posee el controlador. Al cambiar de proveedor, el mapa antiguo también se limpia por la misma ruta.

Implementación en 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() }
}
Video de ejemplo · Progreso de la inicialización
Video aún no grabadoCómo avanza progresivamente InitState desde que se crea el mapa hasta que acepta interacciones. Se puede ver claramente cuándo cambia la indicación de carga.

03 · Eventos

Los controladores que se pasan a la vista tienen la misma configuración en las tres plataformas. Los tipos también son comunes: la carga finalizada recibe el objeto de estado, el toque recibe coordenadas, el cambio de cámara recibe la posición de la cámara.

Evento
Valor recibido
Descripción
onMapLoaded
MapViewState
Carga del mapa completada. Lo habitual es guardar el objeto de estado del argumento y usarlo para operaciones posteriores.
onMapClick
GeoPoint
Toque en el mapa. Para cerrar burbujas de información, colocar pines, etc.
onMapLongClick
GeoPoint
Pulsación larga.
onCameraMoveStart
MapCameraPosition
Inicio de la operación de la cámara. Se llama tanto por interacción del usuario como por movimiento programático.
onCameraMove
MapCameraPosition
Se llama continuamente durante el movimiento. Para la visualización de coordenadas, etc.
onCameraMoveEnd
MapCameraPosition
Cuando se detiene el movimiento. Básicamente, la recuperación de datos debe realizarse aquí.
GoogleMapView · Recepción de eventos
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 */ }

Los eventos relacionados con la cámara también actualizan cameraPosition del objeto de estado, por lo que siempre se puede leer la cámara más reciente sin adjuntar un controlador. Si desea evitar la recuperación durante el movimiento, use solo onCameraMoveEnd.

04 · Vía de escape a nativo

Para cuando la API común no es suficiente, hemos preparado una puerta para bajar a la instancia del mapa nativo. Normalmente no se usa, pero es una vía de escape cuando solo quieres usar una función específica del proveedor en un solo lugar.

MapViewHolder

Holder que envuelve el mapa nativo

El holder posee dos elementos: la vista de la plataforma y la instancia del mapa. El código específico del SDK se confina a partir de aquí y no se filtra al código común.

toScreenOffset / fromScreenOffset

Conversión entre coordenadas y posición en pantalla

Las coordenadas geográficas y las posiciones de píxeles en la pantalla se pueden convertir mutuamente. Se usa al superponer una UI personalizada sobre el mapa.

Recuperación del titular
// Sácalo solo cuando de verdad necesites la API nativa
val holder = mapViewState.getMapViewHolder()
val nativeMap = holder?.map // GoogleMap / MapLibreMap / ...
val offset = holder?.toScreenOffset(point)

El código que usa el titular depende del proveedor. Por favor, separa conscientemente las partes que quieres mantener comunes de las partes donde usas deliberadamente una API específica.

Páginas relacionadas