A Composable with an MPIMapView can be created for use with Jetpack Compose by making use of an AndroidView. This allows an app with a Compose based UI to make use of MPIMapView to display a map.
To allow attaching of an MPIMapViewListener and to call methods of the MPIMapView, MPIMapView is instantiated outside of the AndroidView and its state is saved by remember. The MPIMapViewListener interface is implemented in the mapViewListener
object below and later attached to the mapView
variable.
@Composablefun MappedinComposable() { val ctx = LocalContext.current val mapView by remember { mutableStateOf(MPIMapView(ctx)) }
val mapViewListener = object : MPIMapViewListener { val tag = "MapViewScreen"
override fun onDataLoaded(data: MPIData) { Log.i(tag, "Venue Data Loaded") }
override fun onFirstMapLoaded() { Log.i(tag, "First Map Loaded") } //Implement the rest of the MPIMapViewListener methods… }
The AndroidView used to hold the MPIMapViewListener is shown below. mapView
layout parameters are set to allow it to take up the screen space it is provided. Next, loadVenue
is called. loadVenue
is an MPIMapView function, which accepts MPIOptions.Init containing the venue details and then renders the map.
AndroidView( factory = { mapView.layoutParams = ViewGroup.LayoutParams( ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT, ) mapView.loadVenue( MPIOptions.Init( "5eab30aa91b055001a68e996", "RJyRXKcryCMy4erZqqCbuB1NbR66QTGNXVE0x3Pg6oCIlUR1", "mappedin-demo-mall", ), ) { Log.e("MappedinComposable", "Error loading map view") } mapView.listener = mapViewListener mapView },)
The MPIOptions object contains a venue, clientId, clientSecret, and optional headers. To get started use the Mappedin Id and Secret that has access to demo venues. To start using your venues with the SDK you will need to contact a Mappedin representative to get your own unique Id and Secret.
The MPIMapViewListener named mapViewListener
, which is defined in the code snippet at the beginning of the guide is set as the mapView listener, which is then returned to the factory.
Full Code Sample
The MappedinComposable is now ready to be used in an app. Complete sample code for the MappedInComposable is shown below. This Composable displays a loading indicator until the first map is ready to be shown to the user and then displays the map.
@Composablefun MappedinComposable() { var mapLoaded by remember { mutableStateOf(false) } val ctx = LocalContext.current val mapView by remember { mutableStateOf(MPIMapView(ctx)) }
val mapViewListener = object : MPIMapViewListener { val tag = "MapViewScreen"
override fun onBlueDotPositionUpdate(update: MPIBlueDotPositionUpdate) { Log.i(tag, "Blue Dot Position Update") }
override fun onBlueDotStateChange(stateChange: MPIBlueDotStateChange) { Log.i(tag, "Blue Dot State Change") }
override fun onDataLoaded(data: MPIData) { Log.i(tag, "Venue Data Loaded") }
override fun onFirstMapLoaded() { Log.i(tag, "First Map Loaded") mapLoaded = true }
override fun onMapChanged(map: MPIMap) { Log.i(tag, "Map Changed") }
override fun onNothingClicked() { Log.i(tag, "Nothing Clicked") }
override fun onPolygonClicked(polygon: MPINavigatable.MPIPolygon) { Log.i(tag, "Polygon Clicked") }
override fun onStateChanged(state: MPIState) { Log.i(tag, "State Changed") } }
AndroidView( factory = { mapView.layoutParams = ViewGroup.LayoutParams( ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT, ) mapView.loadVenue( MPIOptions.Init( "5eab30aa91b055001a68e996", "RJyRXKcryCMy4erZqqCbuB1NbR66QTGNXVE0x3Pg6oCIlUR1", "mappedin-demo-mall", ), ) { Log.e("MappedinComposable", "Error loading map view") } mapView.listener = mapViewListener mapView }, ) if (!mapLoaded) { Box( modifier = Modifier.fillMaxSize(), contentAlignment = Alignment.Center, ) { Row(verticalAlignment = Alignment.CenterVertically) { CircularProgressIndicator() } } }}