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
相关产品推荐
相关产品推荐

