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

Polyline动画异常:黑色线条间歇性消失,仅灰色线条动画可见

解决Polyline动画后期黑色线条消失的问题

看起来你遇到了Polyline动画的稳定性问题——一开始功能正常,但运行一段时间后黑色动画线条就消失了,只剩灰色线条在展示。结合你的实现逻辑,我来帮你排查下核心原因和解决办法:

核心问题分析

你每次调用onLocationChanged()都会创建新的Polyline,但没有对旧的线条进行回收管理。时间一长,地图上会堆积大量未被清理的Polyline:

  • 旧的灰色/黑色线条会层层堆叠,新的灰色线条可能直接覆盖在黑色线条之上,导致黑色线条被遮挡
  • 过多的Polyline会占用渲染资源,地图引擎可能会自动隐藏优先级较低的图层,黑色线条大概率会被优先剔除

具体解决方案

1. 维护Polyline实例,每次更新前清理旧线条

添加成员变量来保存当前的黑色和灰色Polyline,在每次触发onLocationChanged()时,先移除上一轮的线条,再创建新的:

// 类成员变量
private Polyline mBlackAnimationPolyline;
private Polyline mGrayStaticPolyline;
private ValueAnimator mCurrentAnimator;
private LatLng mLastLocation; // 保存上一次的位置,用于绘制线条

@Override
public void onLocationChanged(Location location) {
    // 1. 清理旧资源,避免堆积
    if (mBlackAnimationPolyline != null) {
        mBlackAnimationPolyline.remove();
        mBlackAnimationPolyline = null;
    }
    if (mGrayStaticPolyline != null) {
        mGrayStaticPolyline.remove();
        mGrayStaticPolyline = null;
    }
    if (mCurrentAnimator != null && mCurrentAnimator.isRunning()) {
        mCurrentAnimator.cancel();
        mCurrentAnimator = null;
    }
    if (mLastLocation == null) {
        mLastLocation = new LatLng(location.getLatitude(), location.getLongitude());
        return;
    }

    // 2. 创建灰色线条(先隐藏,等黑色动画完成后再显示)
    PolylineOptions grayOpts = new PolylineOptions()
            .add(mLastLocation, new LatLng(location.getLatitude(), location.getLongitude()))
            .color(Color.GRAY)
            .width(8f)
            .zIndex(1f) // 设置图层优先级,低于黑色线条
            .visible(false);
    mGrayStaticPolyline = mMap.addPolyline(grayOpts);

    // 3. 创建黑色动画线条(初始仅显示起点)
    PolylineOptions blackOpts = new PolylineOptions()
            .add(mLastLocation, mLastLocation)
            .color(Color.BLACK)
            .width(8f)
            .zIndex(2f); // 确保黑色线条在图层上层
    mBlackAnimationPolyline = mMap.addPolyline(blackOpts);

    // 4. 执行线条延伸动画
    mCurrentAnimator = ValueAnimator.ofFloat(0f, 1f);
    mCurrentAnimator.setDuration(800);
    mCurrentAnimator.addUpdateListener(anim -> {
        float progress = (float) anim.getAnimatedValue();
        LatLng midPoint = interpolateLocation(mLastLocation, new LatLng(location.getLatitude(), location.getLongitude()), progress);
        mBlackAnimationPolyline.setPoints(Arrays.asList(mLastLocation, midPoint));
    });
    mCurrentAnimator.addListener(new Animator.AnimatorListener() {
        @Override
        public void onAnimationStart(Animator anim) {}

        @Override
        public void onAnimationEnd(Animator anim) {
            // 动画结束后显示灰色线条,按需保留黑色线条
            mGrayStaticPolyline.setVisible(true);
            // 如果不需要保留黑色线条,可在此处移除:
            // mBlackAnimationPolyline.remove();
            // mBlackAnimationPolyline = null;
        }

        @Override
        public void onAnimationCancel(Animator anim) {}

        @Override
        public void onAnimationRepeat(Animator anim) {}
    });
    mCurrentAnimator.start();

    // 更新上一次位置
    mLastLocation = new LatLng(location.getLatitude(), location.getLongitude());
}

// 计算两点间插值位置的工具方法
private LatLng interpolateLocation(LatLng start, LatLng end, float fraction) {
    double lat = start.latitude + (end.latitude - start.latitude) * fraction;
    double lng = start.longitude + (end.longitude - start.longitude) * fraction;
    return new LatLng(lat, lng);
}

2. 额外优化建议

  • 控制Location回调频率:如果位置更新过于频繁(比如每秒多次),会导致动画还未完成就被打断,建议在位置请求时设置合理的间隔(比如setInterval(1000)),或者在动画执行期间忽略新的位置回调
  • 确保操作在UI线程:地图的Polyline操作必须在UI线程执行,如果onLocationChanged()是在后台线程触发的,记得用runOnUiThread()包裹相关代码
  • 检查zIndex设置:给黑色线条设置更高的zIndex值,确保它始终在灰色线条的上层,避免被遮挡

内容的提问来源于stack exchange,提问作者Däñish Shärmä

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.20 11:25:59