Skip to content

Instantly share code, notes, and snippets.

@ArnyminerZ
Created April 1, 2022 11:35
Show Gist options
  • Star 14 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ArnyminerZ/418683e3ef43ccf1268f9f62940441b1 to your computer and use it in GitHub Desktop.
Save ArnyminerZ/418683e3ef43ccf1268f9f62940441b1 to your computer and use it in GitHub Desktop.
osmdroid approach with Jetpack Compose.

Works as expected, however it has some issues with visibility updates such as with AnimatedVisibility blocks, which clears the contents.

However, if you are not hiding the map at any moment, works great. Also works lazyly with LazyColumn or LazyRow.

Feel free to suggest changes.

<?xml version="1.0" encoding="utf-8"?>
<org.osmdroid.views.MapView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/map"
android:layout_width="match_parent"
android:layout_height="match_parent" />
import androidx.compose.runtime.Composable
import androidx.compose.runtime.DisposableEffect
import androidx.compose.runtime.remember
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.platform.LocalLifecycleOwner
import androidx.lifecycle.Lifecycle
import androidx.lifecycle.LifecycleEventObserver
import org.osmdroid.views.MapView
@Composable
fun rememberMapViewWithLifecycle(): MapView {
val context = LocalContext.current
val mapView = remember {
MapView(context).apply {
id = R.id.map
}
}
// Makes MapView follow the lifecycle of this composable
val lifecycleObserver = rememberMapLifecycleObserver(mapView)
val lifecycle = LocalLifecycleOwner.current.lifecycle
DisposableEffect(lifecycle) {
lifecycle.addObserver(lifecycleObserver)
onDispose {
lifecycle.removeObserver(lifecycleObserver)
}
}
return mapView
}
@Composable
fun rememberMapLifecycleObserver(mapView: MapView): LifecycleEventObserver =
remember(mapView) {
LifecycleEventObserver { _, event ->
when (event) {
Lifecycle.Event.ON_RESUME -> mapView.onResume()
Lifecycle.Event.ON_PAUSE -> mapView.onPause()
else -> {}
}
}
}
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.viewinterop.AndroidView
import org.osmdroid.views.MapView
/**
* A composable Google Map.
* @author Arnau Mora
* @since 20211230
* @param modifier Modifiers to apply to the map.
* @param onLoad This will get called once the map has been loaded.
*/
@Composable
fun MapView(
modifier: Modifier = Modifier,
onLoad: ((map: MapView) -> Unit)? = null
) {
val mapViewState = rememberMapViewWithLifecycle()
AndroidView(
{ mapViewState },
modifier
) { mapView -> onLoad?.invoke(mapView) }
}
@MaxCrazy1101
Copy link

Thanks, I think it's what I need<3

@SalmaKHD
Copy link

Hi, when running a preview on the MapView() composable, I only get an empty grid. How can I fix this problem?

@Trevol
Copy link

Trevol commented May 19, 2023

Hi, when running a preview on the MapView() composable, I only get an empty grid. How can I fix this problem?

Salma, try add following snippet to your Activity onCreate method (before setContent {...}):
Configuration.getInstance().load(
applicationContext,
PreferenceManager.getDefaultSharedPreferences(applicationContext)
)

Example you can see here https://github.com/Trevol/wiresag/blob/intelligent_environment_viz/app/src/main/java/com/example/wiresag/WireSagActivity.kt#L46

@SalmaKHD
Copy link

SalmaKHD commented Jun 9, 2023

Thank you so much for your reply!

@TrainerSnow
Copy link

Hey, what license do you publish this to?

@SalmaKHD
Copy link

Hi, one more question: do you know where I can download tiles (.sqlite) for supporting offline mode in specific countries?

@petrospap
Copy link

Hi!
How to use MapLifecycle.kt to draw a simply map by adding GeoPoint lat, lon, zoom etc
I was looking in wiresag that you mention above but is too complex for me to figure out

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment