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

Android谷歌地图路径更新重叠问题解决方案咨询

解决Google Map实时路径更新重叠问题

我仔细看了你的代码,问题主要出在列表引用丢失、重复监听数据变化和标记/路径清除时机不对这几个点上,下面一步步帮你修复:

1. 避免重新初始化标记和路径列表

在onDirectionFinderSuccess里,你重新创建了polylinePaths、originMarkers、destinationMarkers的实例,这会让之前保存的旧标记/路径引用直接丢失,导致后续根本找不到要清除的旧内容。

修改onDirectionFinderSuccess方法:

@Override
public void onDirectionFinderSuccess(List<Route> routes) {
    progressDialog.dismiss();
    // 删掉这三行重新初始化的代码,保留原列表引用
    // polylinePaths = new ArrayList<>();
    // originMarkers = new ArrayList<>();
    // destinationMarkers = new ArrayList<>();
    
    // 先统一清除旧的标记和路径
    clearMapOverlays();

    for (Route route : routes) {
        mMap.moveCamera(CameraUpdateFactory.newLatLngZoom(route.startLocation, 16));
        ((TextView) findViewById(R.id.tvDuration)).setText(route.duration.text);
        ((TextView) findViewById(R.id.tvDistance)).setText(route.distance.text);

        originMarkers.add(mMap.addMarker(new MarkerOptions()
                .icon(BitmapDescriptorFactory.fromResource(R.drawable.start_blue))
                .title(route.startAddress)
                .position(route.startLocation)));

        destinationMarkers.add(mMap.addMarker(new MarkerOptions()
                .icon(BitmapDescriptorFactory.fromResource(R.drawable.end_green))
                .title(route.endAddress)
                .position(route.endLocation)));

        PolylineOptions polylineOptions = new PolylineOptions().geodesic(true).color(Color.BLUE).width(10);
        for (int i = 0; i < route.points.size(); i++)
            polylineOptions.add(route.points.get(i));
        polylinePaths.add(mMap.addPolyline(polylineOptions));
    }
}

新增一个专门的清除方法,统一处理旧覆盖物:

private void clearMapOverlays() {
    // 清除所有起点标记
    for (Marker marker : originMarkers) {
        marker.remove();
    }
    originMarkers.clear();

    // 清除所有终点标记
    for (Marker marker : destinationMarkers) {
        marker.remove();
    }
    destinationMarkers.clear();

    // 清除所有路径
    for (Polyline polyline : polylinePaths) {
        polyline.remove();
    }
    polylinePaths.clear();
}

2. 移除重复的Firebase实时监听

你在onMapReady和onStart里都添加了addValueEventListener,这会导致每次页面启动或地图就绪时新增一个监听,数据变化时多次触发sendRequest,路径自然会叠加。

只保留一个监听,建议放在onCreate里:

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_maps);
    final Intent intent = getIntent();
    myLat = intent.getStringExtra("my_lat");
    myLong = intent.getStringExtra("my_long");
    
    users = new ArrayList<>();
    friends = new ArrayList<>();
    address = new ArrayList<>(); // 确保address是全局初始化的
    databaseReference = FirebaseDatabase.getInstance().getReference("users");

    SupportMapFragment mapFragment = (SupportMapFragment) getSupportFragmentManager()
            .findFragmentById(R.id.map);
    mapFragment.getMapAsync(this);
    btnFindPath = (Button) findViewById(R.id.btnFindPath);
    etOrigin = (EditText) findViewById(R.id.etOrigin);
    etDestination = (EditText) findViewById(R.id.etDestination);

    // 只添加一次实时监听
    databaseReference.addValueEventListener(new ValueEventListener() {
        @Override
        public void onDataChange(DataSnapshot dataSnapshot) {
            users.clear();
            address.clear();
            for(DataSnapshot postSnapShot : dataSnapshot.getChildren()) {
                User user = postSnapShot.getValue(User.class);
                users.add(user);
            }
            // 更新我的位置
            for(int i = 0; i < users.size(); i++) {
                if(users.get(i).getEmail().equals(userEmail)) {
                    myLat = users.get(i).getLatitude();
                    myLong = users.get(i).getLongitude();
                }
                // 收集好友位置(排除自己)
                if(users.get(i).getLatitude() != null && users.get(i).getLongitude()!= null 
                   && !users.get(i).getEmail().equals(userEmail)) {
                    address.add(users.get(i).getLatitude()+","+users.get(i).getLongitude());
                }
            }
            // 先清旧路径再发请求
            clearMapOverlays();
            sendRequest();
        }

        @Override
        public void onCancelled(DatabaseError databaseError) {
            Log.e("MapActivity", "Firebase监听失败", databaseError.toException());
        }
    });
}

然后删除onMapReady和onStart里的重复监听代码。

3. 处理onMapReady里的初始标记

你在onMapReady里添加的初始"My Location"标记没有加入originMarkers列表,导致后续清除操作找不到它。修改这部分:

@Override
public void onMapReady(GoogleMap googleMap) {
    mMap = googleMap;
    LatLng hcmus = new LatLng(Double.parseDouble(myLat), Double.parseDouble(myLong));
    mMap.moveCamera(CameraUpdateFactory.newLatLngZoom(hcmus, 18));
    
    // 将初始标记加入originMarkers,方便后续清除
    Marker initialMarker = mMap.addMarker(new MarkerOptions()
            .title("My Location")
            .position(hcmus));
    originMarkers.add(initialMarker);

    if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
        return;
    }
    mMap.setMyLocationEnabled(true);
}

4. 修正sendRequest里的逻辑

确保起点位置正确获取,并且避免空指针:

private void sendRequest() {
    String origin = null;
    // 找到当前用户的位置作为起点
    for(int i = 0; i < users.size(); i++) {
        if(users.get(i).getEmail().equals(userEmail)) {
            origin = users.get(i).getLatitude()+","+users.get(i).getLongitude();
            break; // 找到后直接退出循环
        }
    }
    
    // 空值判断,避免无效请求
    if(origin == null || address.isEmpty()) {
        Log.e("MapActivity", "起点或终点位置为空");
        return;
    }
    
    try {
        new DirectionFinder(this, origin, address).execute();
    } catch (UnsupportedEncodingException e) {
        e.printStackTrace();
    }
}

现在这些修改应该能彻底解决路径重叠和旧标记残留的问题了,核心就是保持列表引用的一致性、只添加一次实时监听、统一清除旧覆盖物。

内容的提问来源于stack exchange,提问作者S. M. Asif

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.13 09:12:41