Skip to content

MapViewHolderInterface

MapViewHolderInterface proporciona acceso a las instancias nativas de los SDK de mapas para casos de uso avanzados en los que la API unificada de MapConductor no cubre alguna funcionalidad específica del proveedor. Aunque MapConductor ofrece una interfaz común, no envuelve absolutamente todas las funciones nativas; MapViewHolderInterface sirve como puente para esas necesidades.

MapConductor intenta ofrecer una API unificada entre proveedores, pero no siempre es posible conseguir paridad total de funcionalidades. MapViewHolderInterface permite acceder a las instancias nativas subyacentes cuando necesitas características específicas de cada SDK.

interface MapViewHolderInterface<ActualMapViewType, ActualMapType> {
val mapView: ActualMapViewType
val map: ActualMapType
}

Cada implementación de MapViewStateInterface aporta acceso a su MapViewHolderInterface específico:

// Any provider state exposes getMapViewHolder()
val state = rememberGoogleMapViewState()
// May be null until the map is initialized
val holder = state.getMapViewHolder()
// Use the concrete holder type when you need provider-specific APIs
// (e.g. GoogleMapViewHolder / MapboxMapViewHolder / MapLibreMapViewHolder / ...)
// holder?.googleMap?.uiSettings?.isZoomControlsEnabled = false

Implementaciones específicas por proveedor

Section titled “Implementaciones específicas por proveedor”
@Composable
fun MapViewHolderGoogleMapsExample(modifier: Modifier = Modifier) {
val context = LocalContext.current
// Posición de la cámara del mapa
val mapViewState = rememberGoogleMapViewState(
cameraPosition = MapCameraPosition(
position = GeoPoint.fromLatLong(28.53456, 77.192845),
zoom = 12.0
),
)
// Usando mutableStateOf, recomponer cuando cambie mapStyle
var mapStyle by remember { mutableStateOf<MapStyleOptions?>(null) }
// Obtener ViewHolder
val googleMapViewHolder = mapViewState.getMapViewHolder()
LaunchedEffect(googleMapViewHolder, mapStyle) {
if (googleMapViewHolder == null) return@LaunchedEffect
googleMapViewHolder.map.setMapStyle(mapStyle)
}
Column(modifier = modifier) {
Row(
modifier = Modifier.fillMaxWidth(),
) {
Spacer(modifier = Modifier.size(20.dp))
// Google Maps normal
Button(onClick = {
mapStyle = null
}) {
Text(
text = "Normal"
)
}
Spacer(modifier = Modifier.size(20.dp))
// Diseño de mapa simplificado
Button(onClick = {
mapStyle = MapStyleOptions.loadRawResourceStyle(context, R.raw.style_map)
}) {
Text(
text = "Simplified"
)
}
}
GoogleMapView(
state = mapViewState,
modifier = Modifier.fillMaxSize(),
) {}
}
}
class MainActivity : ComponentActivity() {
lateinit var permissionsManager: PermissionsManager
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
enableEdgeToEdge()
if (PermissionsManager.areLocationPermissionsGranted(this)) {
// Procesamiento tras concederse el permiso de acceso a la ubicación (por ejemplo, habilitar LocationComponent del SDK de Maps para mostrar la ubicación del dispositivo).
} else {
permissionsManager = PermissionsManager(this.permissionsListener)
permissionsManager.requestLocationPermissions(this)
}
setContent {
MapConductorSDKTheme {
Scaffold(modifier = Modifier.fillMaxSize()) { innerPadding ->
BasicMapExample(
modifier =
Modifier
.padding(innerPadding)
.fillMaxSize(),
)
}
}
}
}
var permissionsListener: PermissionsListener = object : PermissionsListener {
override fun onExplanationNeeded(permissionsToExplain: List<String>) {
// Mostrar instrucciones para obtener permisos de acceso a la ubicación.
}
override fun onPermissionResult(granted: Boolean) {
if (granted) {
// Procesamiento tras concederse el permiso de acceso a la ubicación (por ejemplo, habilitar LocationComponent del SDK de Maps para mostrar la ubicación del dispositivo).
} else {
// El usuario rechazó el permiso.
}
}
}
}
@Composable
fun BasicMapExample(modifier: Modifier = Modifier) {
val mapViewState = rememberMapboxMapViewState(
cameraPosition = MapCameraPosition(
position = GeoPoint.fromLatLong(35.706400, 139.763635),
zoom = 13.0
),
)
// Obtención de ViewHolder
var mapboxMapViewHolder by remember { mutableStateOf<MapboxMapViewHolder?>(null) }
LaunchedEffect(mapboxMapViewHolder) {
mapboxMapViewHolder?.let { holder ->
with(holder.mapView) {
location.locationPuck = createDefault2DPuck(withBearing = true)
location.enabled = true
location.pulsingEnabled = true
location.puckBearing = PuckBearing.COURSE
location.puckBearingEnabled = true
viewport.transitionTo(
targetState = viewport.makeFollowPuckViewportState(),
transition = viewport.makeImmediateViewportTransition()
)
}
}
}
MapboxMapView(
state = mapViewState,
modifier = modifier,
onMapLoaded = {
mapboxMapViewHolder = mapViewState.getMapViewHolder()
}
) {}
}

En la mayoría de los casos no necesitarás trabajar directamente con MapViewHolderInterface; MapConductor ya ofrece la mayoría de las funciones comunes a través de la API unificada. Sin embargo, es útil cuando:

  • Necesitas acceder a una API nativa que todavía no está envuelta por MapConductor.
  • Quieres integrar extensiones o plugins propios del proveedor.
  • Estás depurando problemas específicos del SDK de mapas subyacente.