Kotlin Android:启用分页后Google Map商家标记不显示
问题分析与修复方案
根据你的描述,ViewModel已能正常接收分页数据,但地图上未显示商家标记,核心问题集中在Activity处理PagingData的逻辑以及分页类的下一页判断逻辑上,以下是具体修复步骤:
1. 修复PagingData遍历逻辑
你在Activity中使用pagingData.map来处理商家数据,但map是用于转换数据集合的操作,不会触发添加标记的副作用代码,必须改用forEach遍历执行标记添加逻辑。同时需要维护一个标记列表,避免重复添加标记。
修改MapsActivity代码:
首先添加标记列表变量:
private val storeMarkers = mutableListOf<Marker>()
然后调整onMapReady中的地图标记处理逻辑:
override fun onMapReady(googleMap: GoogleMap) { mMap = googleMap mMap.uiSettings.apply { isZoomControlsEnabled = true isZoomGesturesEnabled = true isMyLocationButtonEnabled = true } mMap.isMyLocationEnabled = true if (checkPermission()) { if (isLocationEnabled()) { val lastloc = LocationServices.getFusedLocationProviderClient(this).lastLocation lastloc.addOnCompleteListener { task -> if (task.isSuccessful) { val userloc = task.result ?: return@addOnCompleteListener val userexactloc = LatLng(userloc.latitude, userloc.longitude) mMap.moveCamera(CameraUpdateFactory.newLatLngZoom(userexactloc, 17f)) // 仅创建一次范围圆圈,避免重复创建 val circle = mMap.addCircle( CircleOptions() .center(userexactloc) .radius(35000.00) ) lifecycleScope.launch { locViewModel.storelist.collectLatest { pagingData -> // 清除旧标记,避免地图上出现重复标记 storeMarkers.forEach { it.remove() } storeMarkers.clear() // 遍历分页数据,为每个商家添加地图标记 pagingData.forEach { store -> val latitude1 = store.latitude ?: 0.0 val longitude1 = store.longitude ?: 0.0 val storeLatLng = LatLng(latitude1, longitude1) val markerOptions = MarkerOptions() .position(storeLatLng) .title(store.name) .icon(vectorToBitmap(this@MapsActivity, R.drawable.custommark)) .visible(false) val marker = mMap.addMarker(markerOptions) marker?.let { storeMarkers.add(it) } // 计算商家与用户的距离,判断是否显示标记 val distance = SphericalUtil.computeDistanceBetween(userexactloc, storeLatLng) if (distance < circle.radius) { marker?.isVisible = true } } } } } } } } }
2. 修复分页类的下一页判断逻辑
当前分页类中nextKey仅根据当前页数据是否为空判断,会导致请求不存在的页面(比如最后一页有数据但无下一页时)。应改用API返回的hasNextPage字段来判断是否需要加载下一页:
修改StorePagingClass代码:
override suspend fun load(params: LoadParams<Int>): LoadResult<Int, ApiItem> { return try { val page = params.key ?: 1 val response = repository.getStores(page) if (response.isSuccessful) { val apiData = response.body()?.data val data = apiData?.items ?: emptyList() LoadResult.Page( data = data, prevKey = if (page == 1) null else page - 1, // 根据API返回的hasNextPage字段判断是否有下一页 nextKey = if (apiData?.hasNextPage == true) page + 1 else null ) } else { LoadResult.Error(Exception("Failed to load data")) } } catch (e: Exception) { LoadResult.Error(e) } }
3. 额外调试建议
- 在
pagingData.forEach中添加日志,打印商家的经纬度和距离,确认数据是否正确:Log.d("MapsActivity", "商家名称: ${store.name}, 纬度: $latitude1, 经度: $longitude1, 距离用户: $distance 米") - 若标记仍不显示,可临时替换为默认图标测试
vectorToBitmap函数是否正常工作:.icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_RED))
内容的提问来源于stack exchange,提问作者Amirreza
相关产品推荐
相关产品推荐

