安卓,如何从Google地图V2中删除所有标记?

51

我在我的碎片中有一个地图视图。我需要根据条件刷新地图并添加不同的标记。因此,在添加新标记之前,我应该从地图中删除上一个标记。

实际上,几周前应用程序还能正常工作,但突然出现了问题。我的代码如下:

private void displayData(final List<Venue> venueList) {

        // Removes all markers, overlays, and polylines from the map.
        googleMap.clear();
.
.
.
}

在2013年的Android团队I/O大会上,新的Google Map API发布之前,它一直正常工作。但是,之后我修改了代码以使用这个新API。现在,我不知道为什么这个方法googleMap.clear();不起作用了!

欢迎提出任何建议。谢谢。

=======

更新

=======

完整代码:

private void displayData(final List<Venue> venueList) {

        // Removes all markers, overlays, and polylines from the map.
        googleMap.clear();

        // Zoom in, animating the camera.
        googleMap.animateCamera(CameraUpdateFactory.zoomTo(ZOOM_LEVEL), 2000, null);

        // Add marker of user's position
        MarkerOptions userIndicator = new MarkerOptions()
                .position(new LatLng(lat, lng))
                .title("You are here")
                .snippet("lat:" + lat + ", lng:" + lng);
        googleMap.addMarker(userIndicator);

        // Add marker of venue if there is any
        if(venueList != null) {
            for(int i=0; i < venueList.size(); i++) {
                Venue venue = venueList.get(i);
                String guys = venue.getMaleCount();
                String girls= venue.getFemaleCount();
                String checkinStatus = venue.getCan_checkin();
                if(checkinStatus.equalsIgnoreCase("true"))
                    checkinStatus = "Checked In - ";
                else
                    checkinStatus = "";

                MarkerOptions markerOptions = new MarkerOptions()
                        .position(new LatLng(Double.parseDouble(venue.getLatitude()), Double.parseDouble(venue.getLongitude())))
                        .title(venue.getName())
                        .snippet(checkinStatus + "Guys:" + guys + " and Girls:" + girls)
                        .icon(BitmapDescriptorFactory.fromResource(R.drawable.ic_orange_pin));

                googleMap.addMarker(markerOptions);
            }
        }

        // Move the camera instantly to where lat and lng shows.
        if(lat != 0  && lng != 0)
            googleMap.moveCamera(CameraUpdateFactory.newLatLngZoom(new LatLng(lat, lng), ZOOM_LEVEL));

        googleMap.setInfoWindowAdapter(new GoogleMap.InfoWindowAdapter() {
            @Override
            public View getInfoWindow(Marker marker) {
                return null;
            }

            @Override
            public View getInfoContents(Marker marker) {
                return null;
            }
        });

        googleMap.setOnInfoWindowClickListener(new GoogleMap.OnInfoWindowClickListener() {
            @Override
            public void onInfoWindowClick(Marker marker) {
                String str = marker.getId();
                Log.i(TAG, "Marker id: " + str);
                str = str.substring(1);
                int markerId = Integer.parseInt(str);
                markerId -= 1; // Because first item id of marker is 1 while list starts at 0
                Log.i(TAG, "Marker id " + markerId + " clicked.");

                // Ignore if User's marker clicked
                if(markerId < 0)
                    return;

                try {
                    Venue venue = venueList.get(markerId);
                    if(venue.getCan_checkin().equalsIgnoreCase("true")) {
                        Fragment fragment = VenueFragment.newInstance(venue);
                        if(fragment != null)
                            changeFragmentLister.OnReplaceFragment(fragment);
                        else
                            Log.e(TAG, "Error! venue shouldn't be null");
                    }
                } catch(NumberFormatException e) {
                    e.printStackTrace();
                } catch(IndexOutOfBoundsException e) {
                    e.printStackTrace();
                }
            }
        });

3
好的,我已经尝试过了,“clear()”可以运作。你可能做错了什么... - zbr
我调用了这个方法两次。第一次没有问题。第二次,这行代码没有清除标记,并向地图添加新的标记(连同旧的标记)。所以,我很困惑发生了什么。 - Hesam
1
谢谢确认。我会再检查一遍,也许你是对的,我可能做错了什么 :( - Hesam
5个回答

50
好的,最终我找到了一种解决我的问题的替代方法。有趣的问题是,当您将标记分配给地图时,它的id为“m0”。当您从地图中删除它并分配新的标记时,您期望其id应该是“m0”,但实际上是“m1”。因此,它告诉我id是不可信的。所以我在我的片段的onActivityCreated()中定义了List<Marker> markerList = new ArrayList<Marker>();
然后用下面的代码更改上面的代码。如果其他人遇到类似的标记问题,希望这可以帮助他们。
private void displayData(final List<Venue> venueList) {
        Marker marker;

        // Removes all markers, overlays, and polylines from the map.
        googleMap.clear();
        markerList.clear();

        // Zoom in, animating the camera.
        googleMap.animateCamera(CameraUpdateFactory.zoomTo(ZOOM_LEVEL), 2000, null);

        // Add marker of user's position
        MarkerOptions userIndicator = new MarkerOptions()
                .position(new LatLng(lat, lng))
                .title("You are here")
                .snippet("lat:" + lat + ", lng:" + lng);
        marker = googleMap.addMarker(userIndicator);
//        Log.e(TAG, "Marker id '" + marker.getId() + "' added to list.");
        markerList.add(marker);

        // Add marker of venue if there is any
        if(venueList != null) {
            for (Venue venue : venueList) {
                String guys = venue.getMaleCount();
                String girls = venue.getFemaleCount();
                String checkinStatus = venue.getCan_checkin();
                if (checkinStatus.equalsIgnoreCase("true"))
                    checkinStatus = "Checked In - ";
                else
                    checkinStatus = "";

                MarkerOptions markerOptions = new MarkerOptions()
                        .position(new LatLng(Double.parseDouble(venue.getLatitude()), Double.parseDouble(venue.getLongitude())))
                        .title(venue.getName())
                        .snippet(checkinStatus + "Guys:" + guys + " and Girls:" + girls)
                        .icon(BitmapDescriptorFactory.fromResource(R.drawable.ic_orange_pin));

                marker = googleMap.addMarker(markerOptions);
//                Log.e(TAG, "Marker id '" + marker.getId() + "' added to list.");
                markerList.add(marker);
            }
        }

        // Move the camera instantly to where lat and lng shows.
        if(lat != 0  && lng != 0)
            googleMap.moveCamera(CameraUpdateFactory.newLatLngZoom(new LatLng(lat, lng), ZOOM_LEVEL));

        googleMap.setInfoWindowAdapter(new GoogleMap.InfoWindowAdapter() {
            @Override
            public View getInfoWindow(Marker marker) {
                return null;
            }

            @Override
            public View getInfoContents(Marker marker) {
                return null;
            }
        });

        googleMap.setOnInfoWindowClickListener(new GoogleMap.OnInfoWindowClickListener() {
            @Override
            public void onInfoWindowClick(Marker marker) {
                int markerId = -1;

                String str = marker.getId();
                Log.i(TAG, "Marker id: " + str);
                for(int i=0; i<markerList.size(); i++) {
                    markerId = i;
                    Marker m = markerList.get(i);
                    if(m.getId().equals(marker.getId()))
                        break;
                }

                markerId -= 1; // Because first item of markerList is user's marker
                Log.i(TAG, "Marker id " + markerId + " clicked.");

                // Ignore if User's marker clicked
                if(markerId < 0)
                    return;

                try {
                    Venue venue = venueList.get(markerId);
                    if(venue.getCan_checkin().equalsIgnoreCase("true")) {
                        Fragment fragment = VenueFragment.newInstance(venue);
                        if(fragment != null)
                            changeFragmentLister.OnReplaceFragment(fragment);
                        else
                            Log.e(TAG, "Error! venue shouldn't be null");
                    }
                } catch(NumberFormatException e) {
                    e.printStackTrace();
                } catch(IndexOutOfBoundsException e) {
                    e.printStackTrace();
                } catch (NullPointerException e) {
                    e.printStackTrace();
                }
            }
        });
    }

1
如何在不使用clear()方法的情况下从ArrayListMarkerArray中删除所有标记? - Inzimam Tariq IT

39

如果你想要从地图上清除“所有标记、覆盖物和折线”,可以在你的GoogleMap上使用clear()


3
非常热烈欢迎您加入StackOverflow,亲爱的Ahmad。为了避免被踩,回答问题之前请先阅读其他答案,特别是已被采纳的答案。 - Hesam
1
它有助于防止Stackoverflow数据库被重复的答案淹没。谢谢。 - Hesam

11

使用map.clear()从Google地图中删除所有标记。


0
如果您只需要删除标记,而保留其他内容(如地面叠加等),请使用以下代码:
 marker.remove();

或者如果你有很多:

 if(markers!=null&&mMap!=null){                          
      for(int i=0;i<markers.size();i++){                
             markers.get(i).remove();
      }
 }

在哪里

List<Marker> markers = new ArrayList<>();

0
假设有一个包含2个位置的ArrayList。现在,您可以基于该数组在地图上显示标记。将有两个标记。当您单击第一个标记时,它会给您一个标记索引m0,第二个是m1。
假设您刷新了位置数组,现在您得到了一个包含3个位置的数组。您有3个标记。但是,当您单击第一个标记时,它会给您标记索引m2(好像从第一个位置数组开始计数),第二个是m3,第三个是m4。实际上,您想要的是将其设置为m0、m1、m2。
现在,当您构建位置数组时,您可能会调用location.add("your location")...,并且当您重建它(刷新它)时,您首先调用location.clear(),然后再次构建它。
解决方案:

首先,创建另一个类似于位置数组的虚拟数组,并在for循环中与真实的位置数组一起构建:locaionDummy.add(i),但是绝对不要刷新它——这样它就会持续构建,并且您将从一开始就知道有多少个位置。

其次,使用mIndex作为int变量进行如下操作(设置图像示例):

void locatePins() {  

mIndex = locationDummy.size()-location.size();

for (int i = 0; i < userID.size(); i++) {

    LatLng pgLocation = new LatLng(Double.parseDouble(latArr.get(i)), Double.parseDouble(lngArr.get(i)));

    myMap.setInfoWindowAdapter(new GoogleMap.InfoWindowAdapter() {    
        @Override
        public View getInfoWindow(Marker marker) {

        View view = getLayoutInflater().inflate(R.layout.map_marker_info, null);

        RelativeLayout markerInfo= view.findViewById(R.id.markerInfo);
        TextView name = view.findViewById(R.id.userName);
        TextView details = view.findViewById(R.id.userInfo);
        ImageView img = view.findViewById(R.id.userImg);

        name.setText(marker.getTitle());
        details.setText(marker.getSnippet());

        img.setImageBitmap (bmImg.get(Integer.parseInt(marker.getId().replaceAll("[^\\d.]", ""))-mIndex));

        return view;
    }

    @Override
    public View getInfoContents(Marker marker) {

         return null;
    }   

    // ... the rest of the code 
}
}

关键是从 locationDummy.size() 减去实际的 location.size(),得到一个数字 int mIndex,稍后将从 marker.getId() 中减去该数字。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接