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

使用NavController返回后MapView加载崩溃问题排查

MapView返回导航后加载报错:Map size can't be 0 问题解析与修复

错误原因

这个错误的核心是调用newLatLngBounds(LatLngBounds, int)时,MapView还未完成布局测量,当前尺寸为0:

  • 通过NavController的navigateUp()返回页面时,Fragment的View会重新创建,但MapView的onLayout方法尚未执行完成,此时你在onMapReady中调用了依赖地图尺寸的方法(比如你的mapFocus(false)),就会触发该异常。
  • SupportMapFragment内部封装了等待布局完成的逻辑,会自动延迟到View尺寸确定后再执行相关地图操作,因此不会出现这个问题。

你的生命周期实现问题

当前MapView的生命周期管理存在两处问题:

  1. 方法调用顺序错误:onResume中应先调用super.onResume(),再执行mapView.onResume();
  2. 缺失关键生命周期方法:未覆盖onPause和onSaveInstanceState,会导致MapView状态丢失或资源泄漏。

修正后的完整生命周期代码

override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
    super.onViewCreated(view, savedInstanceState)
    mapView = binding.root.findViewById(R.id.gm_resource)
    mapView.onCreate(savedInstanceState)
    mapView.getMapAsync(this)
}

override fun onResume() {
    super.onResume() // 先执行父类生命周期方法
    mapView.onResume()
}

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

override fun onSaveInstanceState(outState: Bundle) {
    super.onSaveInstanceState(outState)
    mapView.onSaveInstanceState(outState) // 保存MapView状态
}

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

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

解决地图视野设置的问题

针对newLatLngBounds的调用,有两种可靠修复方式:

方式1:等待MapView布局完成后再设置视野

在onMapReady中,通过ViewTreeObserver监听MapView的布局完成事件,延迟执行视野设置:

override fun onMapReady(p0: GoogleMap) {
    map = p0
    // 先完成基础配置
    map.uiSettings.isMyLocationButtonEnabled = false
    map.mapType = GoogleMap.MAP_TYPE_SATELLITE
    map.setOnMapClickListener { requireContext().hideKeyboard(binding.root) }
    createClusterManager(map)
    loadResources()
    moveToolbar()

    // 等待MapView布局完成后再设置视野
    mapView.viewTreeObserver.addOnGlobalLayoutListener(object : ViewTreeObserver.OnGlobalLayoutListener {
        override fun onGlobalLayout() {
            // 移除监听,避免重复触发
            mapView.viewTreeObserver.removeOnGlobalLayoutListener(this)
            mapFocus(false) // 此时调用不会报错
        }
    })
}

方式2:使用四参数版本的newLatLngBounds

手动指定地图的宽高尺寸(可根据屏幕尺寸或布局参数估算):

// 假设你需要设置的边界为latLngBounds
val width = resources.displayMetrics.widthPixels
val height = resources.displayMetrics.heightPixels
val padding = 100 // 自定义边距,按需调整
map.moveCamera(CameraUpdateFactory.newLatLngBounds(latLngBounds, width, height, padding))

或先用newLatLngZoom设置初始视野,等布局完成后再调整:

// 先设置默认缩放级别
map.moveCamera(CameraUpdateFactory.newLatLngZoom(centerLatLng, 12f))
// 后续按方式1等待布局完成后调用双参数版本的newLatLngBounds

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.08 02:57:21