# Display Offline Maps

This page talks about displaying installed offline map data with the standard `MapView`, set compatible styles, and use _focusPreviewRegion()_ only as an optional camera helper.

## Use the Standard MapView

The map display page does not require a dedicated Offline `MapView`. The optional _focusPreviewRegion()_ camera helper is invoked through _RegionalOffline_; tile rendering itself does not depend on download-management initialization:

```xml
<ai.nextbillion.maps.core.MapView
    android:id="@+id/mapView"
    android:layout_width="match_parent"
    android:layout_height="match_parent" />
```

Complete Activity example:

```kotlin
class OfflineMapActivity : AppCompatActivity() {
    private lateinit var mapView: MapView
    private var map: NextbillionMap? = null

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_offline_map)

        mapView = findViewById(R.id.mapView)
        mapView.onCreate(savedInstanceState)
        mapView.getMapAsync { nextbillionMap ->
            map = nextbillionMap

            val styleUri = Style.getPredefinedStyle("Bright")
            nextbillionMap.setStyle(Style.Builder().fromUri(styleUri)) {
                intent.getIntExtra("region_id", -1)
                    .takeIf { it >= 0 }
                    ?.let { previewInstalledRegion(nextbillionMap, it) }
            }
        }
    }

    private fun previewInstalledRegion(map: NextbillionMap, regionId: Int) {
        lifecycleScope.launch {
            val installed = withContext(Dispatchers.IO) {
                RegionalOffline.listInstalledRegions()
                    .any { it.regionId == regionId }
            }
            val focused = installed &&
                RegionalOffline.focusPreviewRegion(map, regionId)
            if (!focused) showRegionBoundsUnavailable()
        }
    }

    override fun onStart() {
        super.onStart()
        mapView.onStart()
    }

    override fun onResume() {
        super.onResume()
        mapView.onResume()
    }

    override fun onPause() {
        mapView.onPause()
        super.onPause()
    }

    override fun onStop() {
        mapView.onStop()
        super.onStop()
    }

    override fun onLowMemory() {
        super.onLowMemory()
        mapView.onLowMemory()
    }

    override fun onSaveInstanceState(outState: Bundle) {
        super.onSaveInstanceState(outState)
        mapView.onSaveInstanceState(outState)
    }

    override fun onDestroy() {
        map = null
        mapView.onDestroy()
        super.onDestroy()
    }
}
```

_focusPreviewRegion()_ is only an optional camera helper. A return value of `false` means that no indexable bounds are currently available for the region; it does not affect offline tile loading. The application may also save and restore its own camera position.

## Map Page Integration Requirements

Handle the map page as follows:

-   Forward the full `MapView` lifecycle: _onCreate()_, _onStart()_, _onResume()_, _onPause()_, _onStop()_, _onLowMemory()_, _onSaveInstanceState()_ and _onDestroy()_.

-   After _getMapAsync()_ returns, set the SDK's predefined `Bright` or `Dark` style.

-   When navigating from the download page to the map page, pass `regionId`. If the camera should move automatically, verify that the region is installed on an IO thread, then call _focusPreviewRegion()_ on the main thread.

-   _focusPreviewRegion()_ returns `false`: keep the current camera and prompt the user to locate the region manually. Do not treat this result as an indication that the region data is unavailable.

-   The map's current tile server must be `NGLTomTom`.

-   Do not wait for _previewBundleReady_ on the map page, and do not use the download page resource-status API as a `setStyle()` condition.

-   After returning from the download page, call _MapView.onResume()_ normally. Do not recreate `MapView` or reinitialize `RegionalOffline`.


When using a custom style, the application must ensure that the style, sprite, glyph, TileJSON, and region-tile URL templates are compatible with the current data source.
