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

实现Google Maps Marker显示放大、隐藏缩小动画(仿Uber效果)

实现Google Maps Marker的缩放动画(类似Uber车型选择效果)

我明白你想要实现类似Uber的Marker动画:添加时从无到有放大显示,移除时缩小消失。下面我会基于你现有的代码,给出完整的实现方案。

核心思路

利用Android的ValueAnimator动态控制Marker图标的缩放比例,在添加Marker时执行从0到1的放大动画,在需要隐藏Marker时执行从1到0的缩小动画,动画过程中实时更新Marker的图标,模拟出平滑的弹出/消失效果。

步骤1:封装通用的Marker缩放动画方法

先写一个可复用的动画工具方法,方便在添加和隐藏Marker时调用:

private void animateMarkerScale(final Marker marker, final Bitmap originalIcon, float startScale, float endScale, long duration, final OnAnimationEndListener listener) {
    ValueAnimator animator = ValueAnimator.ofFloat(startScale, endScale);
    animator.setDuration(duration);
    animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
        @Override
        public void onAnimationUpdate(ValueAnimator animation) {
            float scale = (float) animation.getAnimatedValue();
            // 创建缩放后的Bitmap
            Bitmap scaledBitmap = Bitmap.createScaledBitmap(originalIcon, 
                    (int) (originalIcon.getWidth() * scale), 
                    (int) (originalIcon.getHeight() * scale), 
                    true);
            // 更新Marker图标
            marker.setIcon(BitmapDescriptorFactory.fromBitmap(scaledBitmap));
            // 回收临时Bitmap避免内存泄漏
            if (scale != 1f && !scaledBitmap.isRecycled()) {
                scaledBitmap.recycle();
            }
        }
    });
    animator.addListener(new Animator.AnimatorListener() {
        @Override
        public void onAnimationStart(Animator animation) {}

        @Override
        public void onAnimationEnd(Animator animation) {
            if (listener != null) {
                listener.onAnimationEnd();
            }
        }

        @Override
        public void onAnimationCancel(Animator animation) {}

        @Override
        public void onAnimationRepeat(Animator animation) {}
    });
    animator.start();
}

// 定义动画结束回调接口,用于处理动画完成后的逻辑
public interface OnAnimationEndListener {
    void onAnimationEnd();
}

步骤2:修改添加Marker的逻辑(实现放大显示动画)

在你的addDriver方法中,加载原始图标后,先让Marker以极小尺寸显示(视觉上隐藏),再启动放大动画:

private void addDriver(JSONArray jsonArray) {
    // 加载原始Marker图标(替换成你的实际图标资源)
    final Bitmap originalMarkerIcon = BitmapFactory.decodeResource(getResources(), R.drawable.icon);
    
    for (int i = 0; i < jsonArray.length(); i++) {
        String userId = jsonArray.optJSONObject(i).optString("user_id");
        if (!(markersList.containsKey(userId))) {
            LatLng position = new LatLng(
                    Double.parseDouble(jsonArray.optJSONObject(i).optString("user_lat")),
                    Double.parseDouble(jsonArray.optJSONObject(i).optString("user_long"))
            );
            
            // 创建初始状态的Marker:用1x1的极小图标隐藏起来
            Bitmap initialScaledIcon = Bitmap.createScaledBitmap(originalMarkerIcon, 1, 1, true);
            final Marker marker = mGoogleMap.addMarker(new MarkerOptions()
                    .position(position)
                    .snippet(userId)
                    .icon(BitmapDescriptorFactory.fromBitmap(initialScaledIcon)));
            marker.setTag(jsonArray.optJSONObject(i).optString("vehicle_type"));
            
            // 回收初始临时Bitmap
            if (!initialScaledIcon.isRecycled()) {
                initialScaledIcon.recycle();
            }
            
            markersList.put(userId, marker);
            
            // 启动放大动画:从0到1,时长300ms(这个速度贴近Uber的效果,可按需调整)
            animateMarkerScale(marker, originalMarkerIcon, 0f, 1f, 300, null);
        }
    }
}

步骤3:实现Marker缩小隐藏的逻辑

当你需要移除某个Marker时(比如切换车型),先执行缩小动画,动画结束后再移除Marker:

private void removeDriverWithAnimation(String userId) {
    final Marker marker = markersList.get(userId);
    if (marker == null) return;
    
    Bitmap originalIcon = BitmapFactory.decodeResource(getResources(), R.drawable.icon);
    // 启动缩小动画:从1到0,时长300ms
    animateMarkerScale(marker, originalIcon, 1f, 0f, 300, new OnAnimationEndListener() {
        @Override
        public void onAnimationEnd() {
            // 动画结束后彻底移除Marker并从列表中删除
            marker.remove();
            markersList.remove(userId);
        }
    });
}

注意事项

  • 内存管理:动画过程中会创建临时Bitmap,记得在合适时机回收,避免内存泄漏。
  • 图标清晰度:确保你的Marker图标是高分辨率的,避免缩放后出现模糊。
  • 性能优化:如果同时有大量Marker需要执行动画,建议控制并发动画的数量,避免界面卡顿。

这样修改后,你的Marker就会像Uber那样,添加时平滑放大出现,移除时缩小消失啦!

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.28 09:23:05