ai-coding
2026-08-06 ffd19a90a16aca5561bbbda537581b8b41b870bb
移除useAndroidNativeTrip1Callout相关逻辑,使用与ios一致的气泡

Co-Authored-By: 符启基 <fuqj@xiaopeng.com>
2个文件已修改
108 ■■■■■ 已修改文件
src/robotaxi/pages/begin-route/hooks/use-map-markers.ts 62 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/robotaxi/pages/begin-route/hooks/use-view-delegates.tsx 46 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/robotaxi/pages/begin-route/hooks/use-map-markers.ts
@@ -200,8 +200,7 @@
  // 构建上车点 marker
  const createPickupMarker = (
    pickupSite: any,
    useAndroidNativeTrip1Callout: boolean
    pickupSite: any
  ) => {
    if (!(pickupSite?.latitude && pickupSite?.longitude)) return null;
    // 修改目的地预览:起点改为 up-triangle 三角图标 + 名称显示在图标下方,不再用换点图标、不隐藏名称
@@ -226,8 +225,6 @@
      : SITE_NAME_LABEL_BELOW_LG;
    const pickupName = pickupSite?.name || "上车点";
    // 三角态浮窗为富内容(图片/限停),必须走 cover-view customCallout,不能用原生 callout(原生仅支持纯文本)。
    const usePickupRichCallout = isPickupTriangle && !shouldHidePickupName;
    const usePickupNativeCallout = useAndroidNativeTrip1Callout && !usePickupRichCallout;
    const getCustomCalloutAnchorY = () => {
      if ([TripStatus.Publishing, TripStatus.CallingCar].includes(deps.tripStatus)) {
@@ -269,25 +266,7 @@
      ...(isPickupTriangle && !shouldHidePickupName
        ? { label: { content: pickupName, ...pickupNameLabelConfig } }
        : {}),
      ...(!shouldHidePickupName && usePickupNativeCallout
        ? {
            callout: {
              content:
                deps.tripStatus === TripStatus.PublishRoute ||
                deps.showTrip1StyleEndpoint
                  ? `${pickupName} >`
                  : pickupName,
              color: "#FFFFFF",
              fontSize: 12,
              fontWeight: 500,
              bgColor: "#000000",
              borderRadius: 8,
              padding: 8,
              display: "ALWAYS",
              textAlign: "center"
            }
          }
        : !shouldHidePickupName
      ...(!shouldHidePickupName
        ? {
            customCallout: {
              anchorY: getCustomCalloutAnchorY(),
@@ -301,8 +280,7 @@
  // 构建下车点 marker
  const createDropoffMarker = (
    dropoffSite: any,
    useAndroidNativeTrip1Callout: boolean
    dropoffSite: any
  ) => {
    if (!(dropoffSite?.latitude && dropoffSite?.longitude)) return null;
    const dropoffName = [TripStatus.ArrivedDestination].includes(
@@ -318,7 +296,6 @@
      TripStatus.PaymentSuccess
    ].includes(deps.tripStatus);
    const isDropoffTriangle = isDropoffInService || isDropoffSettled;
    const useDropoffRichCallout = isDropoffTriangle; // cover-view 富浮窗
    const getCustomCalloutAnchorY = () => {
      if (!deps.isAndroid && isDropoffSettled) {
        return 6;
@@ -350,22 +327,7 @@
            }
          }
        : {}),
      ...(useAndroidNativeTrip1Callout && !useDropoffRichCallout
        ? {
            callout: {
              content: dropoffName,
              color: "#FFFFFF",
              fontSize: 12,
              bgColor: "#000000",
              borderRadius: 8,
              padding: 8,
              display: "ALWAYS",
              textAlign: "center"
            }
          }
        : {
            customCallout: { anchorY: getCustomCalloutAnchorY(), anchorX: 0, display: "ALWAYS" }
          })
      customCallout: { anchorY: getCustomCalloutAnchorY(), anchorX: 0, display: "ALWAYS" }
    };
  };
@@ -539,16 +501,6 @@
      deps.endSite?.latitude && deps.endSite?.longitude
        ? deps.endSite
        : Taro.getStorageSync("endSite");
    const useAndroidNativeTrip1Callout =
      deps.isAndroid &&
      ([
        TripStatus.PublishRoute,
        TripStatus.VehicleArrivedPickup,
        TripStatus.TripFinished,
        TripStatus.PaymentSuccess,
        TripStatus.CancelOnlyPickup
      ].includes(deps.tripStatus) ||
        deps.showTrip1StyleEndpoint);
    const shouldOffsetPickupMarker =
      deps.statusRule.showPickup
      && deps.statusRule.showDropoff
@@ -561,12 +513,10 @@
            ...pickupSite,
            ...getOffsetCoordinatePoint(pickupSite)
          }
        : pickupSite,
      useAndroidNativeTrip1Callout
        : pickupSite
    );
    const dropoffMarker = createDropoffMarker(
      dropoffSite,
      useAndroidNativeTrip1Callout
      dropoffSite
    );
    const beforeUserDropoffMarker = createBeforeUserDropoffMarker();
    const shouldWaitArrivedDirection =
src/robotaxi/pages/begin-route/hooks/use-view-delegates.tsx
@@ -327,16 +327,6 @@
  /** 修改目的地预览态和接驾态切路线期间隐藏车辆公里/分钟气泡。 */
  const shouldShowVehicleMetricCallout =
    !deps.isModifyDestinationReviewVisible && !deps.isPickupRouteChangeVisible;
  const shouldHideAndroidMarkerCallout =
    deps.isAndroid &&
    ([
      TripStatus.PublishRoute,
      TripStatus.VehicleArrivedPickup,
      TripStatus.TripFinished,
      TripStatus.PaymentSuccess,
      TripStatus.CancelOnlyPickup
    ].includes(deps.tripStatus) ||
      deps.isPickupRouteChangeVisible); // Android 指定状态下隐藏常规 marker 气泡
  const androidCarCalloutContent = useMemo(
    () => (
      <AndroidCarCalloutContent
@@ -355,12 +345,15 @@
  );
  /**
   * Android 接驾态(VehicleApproaching)上车点气泡(customCallout)偶现不绘制,需拖动/缩放/点击后才出现。
   * Android 上车点/下车点气泡(customCallout)偶现不绘制,需拖动/缩放/点击后才出现;
   * 修改目的地预览态下下车点切换为目的地黑色浮窗(endpoint-summary)内容时同样会复现该问题。
   * 在 markers 更新后微调气泡外层(透明容器,无可见样式)的 borderRadius,触发原生地图对该 cover-view 的回流重绘。
   * 该重绘样式(calloutRepaintStyle)应用在 item.id === 1(上车点)和 item.id === 2(下车点)两处 marker 的
   * customCallout 根节点上,覆盖两者各自在不同状态下的内容渲染。
   *
   * iOS 不再做任何 borderRadius 重绘:根因是 translateMarker 平移车标时会丢弃同屏 customCallout,
   * 上车点已改为原生 callout(见 use-map-markers,不受影响);车辆 customCallout 不能靠周期重绘兜底——
   * 实测周期重绘会让气泡每 ~1.5s 闪一下(重绘 churn 本身致闪)。因此该重绘仅保留给 Android。
   * iOS 不再做任何 borderRadius 重绘:根因是 translateMarker 平移车标时会丢弃同屏 customCallout;
   * 车辆 customCallout 不能靠周期重绘兜底——实测周期重绘会让气泡每 ~1.5s 闪一下(重绘 churn 本身致闪)。
   * 因此该重绘仅保留给 Android。
   */
  const [calloutRepaintStyle, setCalloutRepaintStyle] = useState<{
    borderRadius: string;
@@ -380,6 +373,10 @@
  }, []);
  useEffect(() => {
    // 仅 Android 保留一次性重绘兜底;iOS 完全不做 borderRadius 重绘(避免闪动)。
    // 依赖里额外加入 isModifyDestinationReviewVisible / isPickupRouteChangeVisible:
    // 这两个状态切换时 customCallout 内容会切成目的地黑色浮窗(endpoint-summary),
    // 但 marker 的 id/name(markersRepaintSignature)和 tripStatus 通常不变,
    // 若不监听会导致本次内容切换错过重绘时机,出现"气泡背景已渲染但内部文字未绘制"。
    if (!deps.isAndroid) {
      return undefined;
    }
@@ -396,7 +393,14 @@
        calloutRepaintTimerRef.current = null;
      }
    };
  }, [markersRepaintSignature, deps.tripStatus, deps.isAndroid, toggleCalloutRepaint]);
  }, [
    markersRepaintSignature,
    deps.tripStatus,
    deps.isAndroid,
    deps.isModifyDestinationReviewVisible,
    deps.isPickupRouteChangeVisible,
    toggleCalloutRepaint
  ]);
  /**
@@ -493,7 +497,7 @@
          }
          `
        }
        style={item.id === 1 ? calloutRepaintStyle : undefined}
        style={(item.id === 1 || item.id === 2) ? calloutRepaintStyle : undefined}
      >
        {item.isBeforeUserSite ? (
          <CoverView className="before-user-site-callout">
@@ -845,14 +849,6 @@
  const renderMarkerCallout = useCallback((item: any, index: number) => {
    // 故将会变化的限停时长纳入 key,数值变化时强制整体重新挂载而非原地 patch。
    const calloutKey = `callout-${item.id}-${item.name || ''}-${deps.startSite?.time ?? ''}-${deps.isAndroid}`;
    // 待支付/完成态的上/下车点浮窗为富内容(end-site 图片),需走 cover-view,不能被 Android 常规隐藏规则误伤
    const isSettledSiteMarker =
      (item.id === 1 || item.id === 2) &&
      [TripStatus.TripFinished, TripStatus.PaymentSuccess].includes(deps.tripStatus);
    // 到达上车点态的上车点倒计时浮窗(cover-view),同样需放开
    const isArrivedPickupMarker =
      item.id === 1 && deps.tripStatus === TripStatus.VehicleArrivedPickup;
    if (shouldHideAndroidMarkerCallout && !item.isBeforeUserSite && !isSettledSiteMarker && !isArrivedPickupMarker) return null;
    const isWaiting = [TripStatus.Publishing, TripStatus.CallingCar].includes(deps.tripStatus) && index === 0;
    if (isWaiting) return renderWaitingCallout(item, calloutKey);
    // 车辆里程气泡:两端都不再用 marker customCallout 渲染。
@@ -860,7 +856,7 @@
    // 均规避被 translateMarker 丢弃(customCallout 在 iOS translate 下接驾/送驾都会偶发丢失)。
    if (item.name === '车辆位置' && [TripStatus.VehicleApproaching, TripStatus.InService].includes(deps.tripStatus)) return null;
    return renderDefaultCallout(item, calloutKey);
  }, [deps.isAndroid, deps.tripStatus, renderDefaultCallout, renderWaitingCallout, shouldHideAndroidMarkerCallout, deps.startSite?.time]);
  }, [deps.isAndroid, deps.tripStatus, renderDefaultCallout, renderWaitingCallout, deps.startSite?.time]);
  /**
   * 渲染地图覆盖层。