Reputation: 51
I want to develop an Android app using Kotlin and jetpack compose. I want to show a map on the display. For this I want to use openstreetmap. I need a composable function which can show me a map on the display.
All the codes I could find are based on xml UI design and the codes are outdated and do not work if you want to use jetpack compose. I tried to use osmdroid.
Upvotes: 1
Views: 4909
Reputation: 746
You can use AndroidView to use the OSMDroid library's provided views.
For more specifics you can check out Using Views in Compose but here's some example code:
var geoPoint by mutableStateOf(GeoPoint(0.0,0.0))
AndroidView(
modifier = Modifier.fillMaxSize(),
factory = { context ->
// Creates the view
MapView(context).apply {
// Do anything that needs to happen on the view init here
// For example set the tile source or add a click listener
setTileSource(TileSourceFactory.USGS_TOPO)
setOnClickListener {
TODO("Handle click here")
}
}
},
update = { view ->
// Code to update or recompose the view goes here
// Since geoPoint is read here, the view will recompose whenever it is updated
view.controller.setCenter(geoPoint)
}
)
Upvotes: 1
Reputation: 51
I could solve my problem. This is my code.
package com.example.mapapp
import android.content.pm.PackageManager
import android.os.Bundle
import android.preference.PreferenceManager
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Surface
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.viewinterop.AndroidView
import androidx.core.app.ActivityCompat
import androidx.core.content.ContextCompat
import com.example.mapapp.ui.theme.MapAppTheme
import org.osmdroid.config.Configuration
import org.osmdroid.tileprovider.tilesource.TileSourceFactory
import org.osmdroid.views.MapView
import android.Manifest
class MainActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
if (ContextCompat.checkSelfPermission(this, Manifest.permission.INTERNET) != PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(this, arrayOf(Manifest.permission.INTERNET), 0)
}
super.onCreate(savedInstanceState)
setContent {
MapAppTheme {
// A surface container using the 'background' color from the theme
Surface(
modifier = Modifier.fillMaxSize(),
color = MaterialTheme.colorScheme.background
) {
OsmdroidMapView()
}
}
}
val ctx = applicationContext
Configuration.getInstance().load(ctx, PreferenceManager.getDefaultSharedPreferences(ctx))
Configuration.getInstance().userAgentValue = "MapApp"
}
}
@Composable
fun OsmdroidMapView() {
val context = LocalContext.current
AndroidView(
modifier = Modifier.fillMaxSize(),
factory = { context ->
val mapView = MapView(context)
mapView.setTileSource(TileSourceFactory.MAPNIK)
mapView.setBuiltInZoomControls(true)
mapView.setMultiTouchControls(true)
mapView
}
)
}
Upvotes: 0