如何根据Google Map缩放级别缩放自定义标记?附现有绘制代码
实现Google Maps自定义标记随缩放级别缩放的方法
没问题,我来教你搞定这个自定义标记随地图缩放级别动态调整大小的功能,核心思路就是监听地图的相机缩放变化,然后根据当前缩放级别重新计算标记的尺寸并更新它。下面是具体的实现步骤和代码示例:
1. 编写生成缩放后标记Bitmap的方法
首先,我们需要一个方法,根据传入的缩放级别生成对应大小的自定义标记(这里以你用到的圆形为例):
// 缓存不同缩放级别的Bitmap,避免重复创建浪费资源 private HashMap<Float, Bitmap> markerBitmapCache = new HashMap<>(); private Bitmap getScaledMarkerBitmap(float zoomLevel) { // 先检查缓存,存在则直接返回 if (markerBitmapCache.containsKey(zoomLevel)) { return markerBitmapCache.get(zoomLevel); } // 基础尺寸:缩放级别为10时的标记大小,可根据需求调整 int baseSize = 40; // 缩放系数:每增加1级缩放,标记尺寸乘以1.2,可自定义调整缩放速度 float scaleFactor = (float) Math.pow(1.2, zoomLevel - 10); int targetSize = Math.round(baseSize * scaleFactor); // 创建圆形Bitmap Bitmap bitmap = Bitmap.createBitmap(targetSize, targetSize, Bitmap.Config.ARGB_8888); Canvas canvas = new Canvas(bitmap); Paint paint = new Paint(); paint.setColor(Color.RED); // 圆形颜色,可替换 paint.setAntiAlias(true); // 抗锯齿,让圆形更平滑 canvas.drawCircle(targetSize/2f, targetSize/2f, targetSize/2f, paint); // 存入缓存 markerBitmapCache.put(zoomLevel, bitmap); return bitmap; }
2. 在onMapReady中初始化标记并设置相机监听
接下来,在你的onMapReady方法里,添加初始标记,并设置相机空闲监听(相机停止缩放/移动后触发,避免频繁更新影响性能):
@Override public void onMapReady(GoogleMap googleMap) { mMap = googleMap; // 保留你原有的地图样式设置代码 try { boolean success = mMap.setMapStyle(MapStyleOptions.loadRawResourceStyle(getContext(), R.raw.style_json)); if (!success) { Log.e("MapsActivityRaw", "Style parsing failed."); } } catch (Resources.NotFoundException e) { Log.e("MapsActivityRaw", "Can't find style.", e); } final LatLng myLatlng = new LatLng(-33.999564, 18.516763); // 创建初始标记,使用当前地图缩放级别生成的Bitmap MarkerOptions markerOptions = new MarkerOptions() .position(myLatlng) .icon(BitmapDescriptorFactory.fromBitmap(getScaledMarkerBitmap(mMap.getCameraPosition().zoom))); final Marker myMarker = mMap.addMarker(markerOptions); // 移动相机到初始位置,设置初始缩放级别为10 mMap.moveCamera(CameraUpdateFactory.newLatLngZoom(myLatlng, 10)); // 设置相机空闲监听,缩放完成后更新标记大小 mMap.setOnCameraIdleListener(new GoogleMap.OnCameraIdleListener() { @Override public void onCameraIdle() { float currentZoom = mMap.getCameraPosition().zoom; // 更新标记的图标 myMarker.setIcon(BitmapDescriptorFactory.fromBitmap(getScaledMarkerBitmap(currentZoom))); } }); }
3. 清理缓存避免内存泄漏
最后,在页面销毁时记得清理缓存的Bitmap,防止内存泄漏:
@Override public void onDestroy() { super.onDestroy(); // 遍历缓存回收Bitmap for (Bitmap bitmap : markerBitmapCache.values()) { if (!bitmap.isRecycled()) { bitmap.recycle(); } } markerBitmapCache.clear(); }
额外说明
- 如果你的地图上有多个标记,可以把所有Marker存入一个
List<Marker>,然后在onCameraIdle中遍历列表逐个更新图标。 - 缩放系数
1.2和基础尺寸40可以根据你的视觉需求调整,比如想要标记缩放更快,可以把系数调大到1.3或1.4。 - 如果你用的是自定义Drawable而不是绘制圆形,也可以用
Drawable.setBounds()调整大小后再转成Bitmap,逻辑是一样的。
内容的提问来源于stack exchange,提问作者ClassA
相关产品推荐
相关产品推荐

