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

Android打车应用MapView路线动画叠加多段线不对齐问题求助

问题原因
  • 端点样式未统一:Google Maps Polyline 默认端点为ButtCap(平切端点),你没有显式配置前景、背景多段线的端点样式,截断后的前景多段线两端的平切边缘,和背景多段线连续线段的圆角关节渲染效果不一致,产生视觉偏移。
  • 点集截断丢失关节信息:按点数截断点集时,如果刚好切到曲线拐点位置,前景多段线会丢失拐点前后的过渡点,JointType.ROUND 圆角关节的渲染逻辑和完整背景多段线的同位置关节渲染产生差异,导致偏移。
  • 点集来源不稳定性:你直接从backgroundPolyline.points获取点集,部分版本的Google Maps SDK会对返回的点做轻微的坐标归一化处理,和原始传入的坐标存在极小误差,叠加后就会出现可见偏移。
解决方案

方案1:优先推荐 采用Pattern动态填充实现动画(完全避免对齐问题)

不需要动态截断点集,两条多段线使用完全相同的完整坐标点,通过动态修改前景多段线的填充 pattern 实现动画效果,从根源上消除对齐问题:

// 初始化阶段 自己存储原始坐标点集合,所有点操作优先用这个集合
val originalPoints: List<LatLng> = // 你生成的曲线点集

val polylineOptions = PolylineOptions()
        .color(backgroundColor)
        .width(POLYLINE_WIDTH)
        .geodesic(false)
        .jointType(JointType.ROUND)
        .startCap(RoundCap())
        .endCap(RoundCap())
        .zIndex(0f)
        .addAll(originalPoints)
backgroundPolyline = map.addPolyline(polylineOptions)

val foregroundPolylineOptions = PolylineOptions()
        .color(foregroundColor)
        .width(FOREGROUND_POLYLINE_WIDTH)
        .jointType(JointType.ROUND)
        .geodesic(false)
        .startCap(RoundCap())
        .endCap(RoundCap())
        .zIndex(1f)
        .addAll(originalPoints) // 和背景完全一致的完整点集
foregroundPolyline = map.addPolyline(foregroundPolylineOptions)

// 动画更新逻辑
override fun onAnimationUpdate(animation: ValueAnimator) {
    val fraction = animation.animatedFraction
    // pattern单位为屏幕像素,你也可以用地图投影换算成实际地理长度匹配行程
    val totalPatternLength = 1000f // 自定义总长度,按视觉效果调整即可
    val gapLength = totalPatternLength * (1 - fraction)
    val foregroundLength = totalPatternLength * 0.1f // 10%长度的前景滑块
    foregroundPolyline.pattern = listOf(
        Gap(gapLength),
        Stroke(foregroundLength),
        Gap(totalPatternLength - gapLength - foregroundLength)
    )
}

方案2:修复原有截断逻辑

如果你要保留现有截断点的实现,修改以下几点即可:

  1. 不要从已渲染的polyline实例中读取点集,统一使用你自己存储的原始坐标点集合originalPoints
  2. 显式给两条多段线添加相同的startCap和endCap配置
  3. 截断点前后各多保留1个点,避免丢失拐点信息:
override fun onAnimationUpdate(animation: ValueAnimator) {
    val totalSize = originalPoints.size
    val foregroundEnd = ceil(animation.animatedFraction * totalSize).toInt()
    val foregroundPointCounts = (totalSize * 0.1).toInt()
    val start = max(0, foregroundEnd - foregroundPointCounts - 1) // 多保留前1个点
    val end = min(totalSize, foregroundEnd + 1) // 多保留后1个点
    // 转成新列表避免subList视图特性导致的异常
    foregroundPolyline.points = ArrayList(originalPoints.subList(start, end))
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.10 18:24:00