Open ravenfeld opened 2 years ago
Hi @ravenfeld I have not used compose before. What is it for? If you don't find documentation on how to do this, feel free to start a new readme or so and submit a pull request...
https://developer.android.com/jetpack/compose
This is a new way to create views on Android. It's a bit like Swift UI I think.
I am using maplibre in compose and it is working flawlessly. I have checked how google made the GoogleMap composable function and mimic that solution. Underneath it is just an AndroidView composable, which is interop for classic XML. Here are some utils that I am using: https://gist.github.com/PiotrPrus/d65378c36b0a0c744e647946f344103c and here is a small sample of using it:
val map = rememberMapViewWithLifecycle()
AndroidView(
modifier = Modifier.fillMaxSize(),
factory = { map },
update = { mapView ->
coroutineScope.launch {
val libreMap = mapView.awaitMap()
libreMap.setStyle(
Style.Builder().fromJson(
ResourceReader.readRawResource(
context,
R.raw.mapbox_style
) ?: ""
)
)
}
)
thanks a lot, that's what I was starting to look at. I'm just having trouble with the listeners doing leaks
which listeners? Maybe you need to observe the compose lifecycle or make some activity listeners and observe them in slide effects?
Sorry I didn't see your message. I also looked at Google Map and they did a lot of things on their side and not just put in an AndroidView. I don't know what the performance impact is. And my code for drawing lines on the map is not very clean at the moment I think. Google map exposed the components in Composable on their side.
Hey folks, I'm using the official Mapbox SDK for Android at the moment in a Jetpack Compose app and had to adapt it to make it work. Here's what I'm doing more or less: https://gist.github.com/daniel-j-h/cd88b6cdf54e86bffed2bc440cbbb751
By now there is Google Maps for Compose, with a nice API; easy to use
The official Mapbox SDK for Android still does not provide a similar API for Compose; there's an in-progress pull request upstream from summer 2022 but there seems to be no progress from what I can tell.
Ideally we would have a Google Maps for Compose like API and beat Mapbox to a great developing experience going forward :)
Thank you very much, I have started a work with Mapbox and we are relasioning with them. I am in the process of getting mapbox into compose but not sure if my company will allow me to do the same in opensource for maplibre.
@RomanBapst and I have been working on such a library, both for MapLibre and Mapbox. It is called ramani-maps: https://github.com/ramani-maps/ramani-maps.
It does not have all the features (we added what we use first, obviously), but we intend to keep adding features steadily, and we are open to contributions :blush:.
I hope this helps!
I am using maplibre in compose and it is working flawlessly. I have checked how google made the GoogleMap composable function and mimic that solution. Underneath it is just an AndroidView composable, which is interop for classic XML. Here are some utils that I am using: https://gist.github.com/PiotrPrus/d65378c36b0a0c744e647946f344103c and here is a small sample of using it:
val map = rememberMapViewWithLifecycle() AndroidView( modifier = Modifier.fillMaxSize(), factory = { map }, update = { mapView -> coroutineScope.launch { val libreMap = mapView.awaitMap() libreMap.setStyle( Style.Builder().fromJson( ResourceReader.readRawResource( context, R.raw.mapbox_style ) ?: "" ) ) } )
I wouldn't set the style in the update
maybe better in the Factory? so it's not called every time we want to update markers or camera position. but probably this is just an example, it's very helpful, Thank you!
It's not as simple as that: you also have to follow the lifecycle to warn a map. Looking at google maps, that's what they do. The project above does it very well.
It seems like there is an issue with NativeConnectivityListener
when trying to use MapLibre in Compose Previews.
Digging into this, it looks like it's some sort of native loader, which shouldn't be an issue inherently, but I am starting to realize that Compose Previews have several non-obvious limitations, including network and certain file APIs being unavailable.
Has anyone else gotten Compose Previews to work yet? This is clearly the modern way to do Android development, and not being able to use MapLibre here would be unfortunate.
Here is my code so far.
/**
* Remembers a MapView and gives it the lifecycle of the current LifecycleOwner
*/
@Composable
fun rememberMapViewWithLifecycle(): MapView {
val context = LocalContext.current
val mapView = remember { MapView(context) }
// Makes MapView follow the lifecycle of this composable
val lifecycle = LocalLifecycleOwner.current.lifecycle
DisposableEffect(lifecycle, mapView) {
val lifecycleObserver = getMapLifecycleObserver(mapView)
lifecycle.addObserver(lifecycleObserver)
onDispose {
lifecycle.removeObserver(lifecycleObserver)
}
}
return mapView
}
private fun getMapLifecycleObserver(mapView: MapView): LifecycleEventObserver =
LifecycleEventObserver { _, event ->
when (event) {
// Lifecycle.Event.ON_CREATE -> mapView.onCreate(Bundle())
Lifecycle.Event.ON_START -> mapView.onStart()
Lifecycle.Event.ON_RESUME -> mapView.onResume()
Lifecycle.Event.ON_PAUSE -> mapView.onPause()
Lifecycle.Event.ON_STOP -> mapView.onStop()
Lifecycle.Event.ON_DESTROY -> mapView.onDestroy()
else -> throw IllegalStateException()
}
}
@Composable
fun NavigationMapView() {
val mapView = rememberMapViewWithLifecycle()
AndroidView(
modifier = Modifier.fillMaxSize(),
factory = { mapView },
update = { mapView ->
mapView.getMapAsync { map ->
map.setStyle("https://demotiles.maplibre.org/style.json")
}
}
)
}
@Preview
@Composable
fun PreviewNavigationMap() {
Mapbox.getInstance(LocalContext.current)
NavigationMapView()
}
I've attempted to do some crimes against the JVM and use ByteBuddy to replace the class at runtime, but am like 12 layers deep into weeds and way out of my range of comfort with Java. If my hunch is correct, it seems like MapLibre should allow for a mock connectivity listener implementation to enable previews, and I was hoping to confirm quickly with hacks, but that's proving to be difficult 😅
Are there any plans to add native Jetpack Compose support?
I spoke with @JonasVautherin and I think I remember he said there are not really any disadvantages having it as a separate project. So for now I recommend using Ramani Maps.
Long term it makes sense to have Jetpack Compose support and if anyone wants to integrate this functionality a PR would be welcome.
Yeah, I really don't see any disadvantage, and I don't see how it could be done in a more "native" way than what Ramani Maps does. I could see a governance issue (i.e. if you have a problem using Ramani Maps because it is not officially owned by the MapLibre project), but technically I think it is as native as it gets (well "more native" could be by calling C++ directly instead of using MapLibre Android, but IMHO it would be a poor idea).
Ramani Maps looks promising. However being a separate project it probably won't get the latest beta or pre-release versions of Maplibre..
However being a separate project it probably won't get the latest beta or pre-release versions of Maplibre...
Can't you just tell gradle to point to a different version of the dependency when including org.ramani-maps:ramani-maplibre
, e.g. like this? :thinking:
Yes. Gradle is a complex beast to understand, but this is totally possible. And doesn’t require merging higher level wrappers like Ramani or the similar SwiftUI project into the main repo.
However being a separate project it probably won't get the latest beta or pre-release versions of Maplibre...
Can't you just tell gradle to point to a different version of the dependency when including
org.ramani-maps:ramani-maplibre
, e.g. like this? 🤔
Thanks! Indeed, it looks like a good option.
Hi, I'm going to start an application in Android Compose. I wanted to know if the project will put the view in Compose or if there is an example to know how to do it.
Thanks in advance.