You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Jetpack Compose项目中使用osmdroid出现无地图方格界面问题求助

解决Jetpack Compose中Osmdroid显示方格无地图的问题

核心问题分析与修复步骤

1. XML布局语法错误

你的LinearLayout标签缺少空格,导致布局解析异常:
错误代码:

<LinearLayoutxmlns:android="http://schemas.android.com/apk/res/android"

修复后:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"

2. 未正确初始化MapView,存在空指针风险

你声明了lateinit var map: MapView但从未初始化,直接调用map.controller会抛出空指针异常。应直接使用ViewBinding获取XML中的MapView实例:
修正后的onCreate方法片段:

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    binding = LayoutBinding.inflate(layoutInflater)
    val view = binding.root

    // 初始化osmdroid配置
    Configuration.getInstance().load(this, PreferenceManager.getDefaultSharedPreferences(this))
    setContentView(view)

    // 使用binding获取MapView实例
    val map = binding.map
    val mapController = map.controller
    mapController.setZoom(9.5f)
    val startPoint = GeoPoint(32.627387981943, 51.62582233021288)
    mapController.setCenter(startPoint)
    map.setTileSource(TileSourceFactory.MAPNIK)
    // 启用内置缩放控件
    map.setBuiltInZoomControls(true)
    map.setMultiTouchControls(true)

3. 重复创建MapView导致布局冲突

你同时在XML中添加了MapView,又在Compose的MapCarScreen里新建了另一个MapView,两个视图重叠会导致显示异常。二选一即可,推荐纯Compose实现:

纯Compose实现代码

  1. 移除XML中的MapView,直接在Activity中使用setContent
  2. 修改Activity代码:
class XmlClass : ComponentActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        // 初始化osmdroid配置
        Configuration.getInstance().load(this, PreferenceManager.getDefaultSharedPreferences(this))
        // 动态请求危险权限
        requestPermissions(arrayOf(Manifest.permission.INTERNET, Manifest.permission.ACCESS_FINE_LOCATION), 100)
        
        setContent {
            val navController = NavHostController(this)
            MapCarScreen(navController)
        }
    }
}
  1. 修改MapCarScreen,正确配置MapView:
@Composable
fun MapCarScreen(navController: NavHostController) {
    Box(modifier = Modifier.fillMaxSize()) {
        AndroidView(
            factory = { context ->
                MapView(context).apply {
                    setTileSource(TileSourceFactory.MAPNIK)
                    controller.setZoom(9.5f)
                    val startPoint = GeoPoint(32.627387981943, 51.62582233021288)
                    controller.setCenter(startPoint)
                    setBuiltInZoomControls(true)
                    setMultiTouchControls(true)
                }
            },
            modifier = Modifier.fillMaxSize()
        ) { mapView ->
            // 绑定生命周期,确保地图正确销毁
            val lifecycleOwner = LocalLifecycleOwner.current
            lifecycleOwner.lifecycle.addObserver(mapView)
        }
    }
}

4. 权限与依赖检查

  • 清理重复权限,保留必要项:
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
  • 确保build.gradle中添加osmdroid依赖(替换为最新版本):
dependencies {
    implementation 'org.osmdroid:osmdroid-android:6.1.18'
}
  • 确认项目仓库包含mavenCentral:
repositories {
    mavenCentral()
}

5. 瓦片加载优化

如果仍显示方格,可尝试:

  • 切换瓦片源,比如TileSourceFactory.OPENSTREETMAP
  • 设置本地缓存路径:
val storage = getExternalFilesDir(null)?.absolutePath ?: filesDir.absolutePath
Configuration.getInstance().setOsmdroidBasePath(File(storage))
Configuration.getInstance().setOsmdroidTileCache(File(storage, "tiles"))

内容的提问来源于stack exchange,提问作者Amir Dorri

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.01 04:55:28