Android: Ids of Markers of Google Maps - android

I have an app with TabHost and Google Maps. When I click on the tab that contains the Map, I do map.clear(). But this only cleans 7 markers. When I create the markers again, the id does not start from m0 but from m8.
How I can start the ids of the markers from 0?
thanks

You cannot control what ids will be generated by the API.
One thing you can do is to remove and recreate whole MapFragment or MapView, but that's an overkill.

Actually there is a trick to solve this .
//while plotting
int myId=0;
MarkerOptions markerOptions = new MarkerOptions()
.position("YOUR LATLNG VARIABLE")
.snippet(""+myId)
.icon(BitmapDescriptorFactory.fromResource(R.drawable.orange_map01));
myId++;
//then in the marker click listener function.
gmap.setOnMarkerClickListener(new OnMarkerClickListener() {
#Override
public boolean onMarkerClick(final Marker arg0) {
// TODO Auto-generated method stub
System.out.println("The id you assigned will be available based on the click "+arg0.getSnippet());
//Do what ever you want to do with the assigned id , id will be created newly everytime.
Yourlist.get(arg0.getsnippet);
}
}

Related

How to manage click on marker which is not in Cluster in Android Google Map API?

I am having trouble implementing OnClickListener for Marker(s) which are not in Cluster, i.e. not added using:
mClusterManager.addItem(markerCluster);
I have set OnMarkerClickLister as follows:
mMap.setOnCameraIdleListener(mClusterManager);
mMap.setOnMarkerClickListener(mClusterManager);
If I just use:
mMap.setOnMarkerClickListener(new GoogleMap.OnMarkerClickListener() {
#Override
public boolean onMarkerClick(Marker marker) {
return false;
}
});
the click on markers is not working at all.
For example: I have this situation:
Two green dots and big blue dot (with number 6) are one Cluster, but the red marker is not in Cluster as I don't want it to be Clustered like other markers.
InfoWindow is normally showing when I click on red marker, but onMarkerClick doesn't work - as well as OnClusterItemClickListener. But OnClusterItemClickListener works when I click on markers which are in Cluster.
Hope you understand what I am trying to achieve. If not, please let me know.
Updated answer
The image that you added in your edit explains the issue clearly, thanks for that!
In order too solve this issue we need to register the listener differently. Namely: by registering it to the ClusterManager's MarkerManager as that class handles everything of the markers now. We also need to add the NormalMarkers a bit differently, so lets go through it step by step:
1) Update the OnMarkerClickListener of the mMap:
mMap.setOnMarkerClickListener(mClusterManager.getMarkerManager()); // Note the `MarkerManager` here
2) This MarkerManager holds all the collections. We need to create a new collection on this manager to which we will add the NormalMarkers that should be displayed apart from the clusters:
MarkerManager.Collection normalMarkersCollection = mClusterManager.getMarkerManager().newCollection();
3) Adding the markers is done similar to how this was before, but with using the addMarker() method on the collection that we created. We must pass a MarkerOptions() object to this:
// Create a normal marker
val markerOptions = MarkerOptions()
.position(new LatLng(...))
.title("My marker")
.snippet("With description")
// Add it to the collection
normalMarkersCollection.addMarker(markerOptions)
4) Last but not least: we want the OnClickListener on it:
normalMarkersCollection.setOnMarkerClickListener(new GoogleMap.OnMarkerClickListener {
public boolean onMarkerClick(marker: Marker) {
// NORMAL MARKER CLICKED!
return false;
}
})
5) Done! Now the normal markers are added to the map just like before, but with a working OnMarkerClickListener.
Earlier answer
(Setting the click listeners for the clusters and clustered items)
You should add the clicklistener to the mClusterManager. Setting the clicklistener on the mMap does not work when using the ClusterManager.
Thus instead of using mMap.setOnMarkerClickListener, set the ClusterItemClickListener on the cluster manager:
mClusterManager.setOnClusterItemClickListener(new ClusterManager.OnClusterItemClickListener<MyItem>() {
#Override
public boolean onClusterItemClick(MyItem item) {
Log.d("cluster item","clicked");
return true;
}
});
Additionally, if you want to capture the onclick of the clustered item item, use the ClusterClickListener:
mClusterManager.setOnClusterClickListener(new ClusterManager.OnClusterClickListener<MyItem>() {
#Override
public boolean onClusterClick(Cluster<MyItem> cluster) {
Log.d("cluster","clicked");
return true;
}
});
If you want to have both Marker and Cluster listeners working you can write
mGoogleMap.getMarkerManager().onMarkerClick(marker);
inside your OnMarkerClickListener

Android Google Map V2: How to change previous clicked marker's icon when clicked on another marker

UPDATE: I have solved the performance issue by adding a previousMarker object. So only the previous clicked marker will be remove and replaced with the default icon. However the info window is still not shown when I click on the marker.
I have a map view and set some markers on it. What I want is when I clicked on a marker, it changes its icon to be a different icon, and when I click on another marker, the previous marker's icon should change to its original one.
What I've done is something like this but it just simply changes the marker icon whenever I click on the marker.
#Override
public boolean onMarkerClick(Marker marker) { //Called when a marker has been clicked or tapped.
LatLng markerPos=marker.getPosition();
String markerLocationName=marker.getTitle();
String markerSubCategoryName=marker.getSnippet();
marker.remove();
MarkerOptions markerOptions =
new MarkerOptions().position(markerPos)
.title(markerLocationName)
.snippet(markerSubCategoryName)
.icon(BitmapDescriptorFactory.fromResource(R.drawable.new_icon));// Changing marker icon
mMap.addMarker(markerOptions);
Log.d("marker","change marker icon"); // can open a dialog window here
return false;
}
So if I click 2 markers, I will get 2 new icons appears, meanwhile what I want is only the current clicked marker changes its icon.
So I've also done something like this by adding 2 more lines of code. It succeeds doing what I want but it has some drawback (see below).
#Override
public boolean onMarkerClick(Marker marker) { //Called when a marker has been clicked or tapped.
mMap.clear();
populateAllMarkersOnMap();//repopulate markers on map
LatLng markerPos=marker.getPosition();
String markerLocationName=marker.getTitle();
String markerSubCategoryName=marker.getSnippet();
marker.remove(); //remove the current clicked marker
MarkerOptions markerOptions =
new MarkerOptions().position(markerPos)
.title(markerLocationName)
.snippet(markerSubCategoryName)
.icon(BitmapDescriptorFactory.fromResource(R.drawable.new_icon));// Changing marker icon
mMap.addMarker(markerOptions); //add marker with new icon into map
return false;
}
The drawback is 1/ it "disable" the info window (the same thing also happen in the first way). 2/ it clear all the markers on map and set all the markers again. Imagine I have 100 markers, should that be a performance problem on every click I do?
The populateAllMarkersOnMap() can be something as simple like this at the moment:
private void populateAllMarkersOnMap(){
setMarker(latA1, lonA1, "A1","A1.1");
setMarker(latA2, lonA2, "A2","A2.1");
// ... (100 times or populated via a loop)
};
So is there a way to get previous clicked marker to change its icon back to default when I click a new marker? Apologise for my English, if you think I should put another title for my question, please help.
Finally I found the best and most simple way. I made a previousMarker object and store the current clicked marker:
#Override
public boolean onMarkerClick(Marker marker) { //Called when a marker has been clicked or tapped.
if(previousMarker!=null){
previousMarker.setIcon(BitmapDescriptorFactory.fromResource(R.drawable.dot_icon));
}
marker.setIcon(BitmapDescriptorFactory.fromResource(R.drawable.ct_icon));
previousMarker=marker; //Now the clicked marker becomes previousMarker
return false;
}
You might be looking for this method probably
Called when the marker's info window is closed.
optional public func mapView(mapView: GMSMapView, didCloseInfoWindowOfMarker marker: GMSMarker)
I found the best and most simple way. I made another marker object and store the current clicked marker enter code here
#Override
public boolean onMarkerClick(Marker marker) { //Called when a marker has been clicked or tapped.
if(previousMarker!=null){
marker2.setIcon(BitmapDescriptorFactory.fromResource(R.drawable.dot_icon));
}
marker.setIcon(BitmapDescriptorFactory.fromResource(R.drawable.ct_icon));
marker2=marker; //Now the clicked marker becomes previousMarker
return false;
}

How remove a single marker by Id?

this code is remove with click infoWindow
// Setting click event handler for InfoWIndow
googleMap.setOnInfoWindowClickListener(new OnInfoWindowClickListener() {
#Override
public void onInfoWindowClick(Marker marker) {
// Remove the marker
marker.remove();
}
});
but, How remove a single marker by Id without click infoWindow ? i will remove by Button View
Whenever you add the marker to map don't forget to keep its record, like adding it to Map or ArrayList.
your_google_map_obj.addMarker(new MarkerOptions()) //this adds Marker on Google Map, you
should know it always returns Marker object so that you can use it later especially for
removal
so Marker marker=your_google_map_obj.addMarker(new MarkerOptions()) add this marker object to list or map markerArraylist.add(marker); then easily you can extract marker from list by Marker marker=markerArraylist.get(index); and then call marker.remove();
Other way to do it
After adding the marker it is possible to obtain its reference:
Marker marker = map.addMarker(..);
Marker class has remove method, check this documentation

Differentiate between different markers in Maps API v2 (unique identifiers)

I have an ArrayList of a custom class. There are about 10 objects in the list, each with details like Title, Snippet, LatLng. I have successfully added all 10 to a Map by using my custom class functions like getTitle, getSnippet, getLatLng etc.
Now, when I click the info window (of the marker), I want to be able to somehow KNOW which object of my custom class does that marker correspond to.
For example, if I click the McDonald's market, I want to be able to know which item from my ArrayList did that marker belong to.
I've been looking at the MarkerOptions and there doesn't seem to be anything in there that I can use to identify the relevant custom object with.
If the question is too confusing, let me make it simple:
ArrayList<CustomObj> objects = blah
map.addMarker(new MarkerOptions().position(new LatLng(
Double.parseDouble(result.get(i).getCompanyLatLng()
.split(",")[0]), Double.parseDouble(result
.get(i).getCompanyLatLng().split(",")[1])))
.title(result.get(i).getCompanyName())
.snippet(result.get(i).getCompanyType())
.icon(BitmapDescriptorFactory
.fromResource(R.drawable.pin)));
Now when this is clicked, I go on to the next page. The next page needs to know WHICH object was clicked so that I can send the other details to that page (e.g. Image URLs that need to be loaded etc).
How do I add a unique integer or any identifier to my marker?
One correct way is to use Map<Marker, CustomObj> which stores all markers:
Marker marker = map.addMarker(...);
map.put(marker, result.get(i));
and in onInfoWindowClick:
CustomObj obj = map.get(marker);
Another try is using Android Maps Extensions, which add getData and setData method to Marker, so you can assign your CustomObj object after creating marker and retrieve it in any callback.
I used the the snippet text for saving an unique ID. If you need the snippet it's will be for the popup and there you can just make your own (by finding the object from the ID) so you wont miss it but you'll certainly miss a unique ID for identifying the objects.
To find the right object I just iterate through them:
for(SomeObject anObject : someObjects) {
if(marker.getSnippet().equalsIgnoreCase(anObject.getID())) {
//you got at match
}
}
According to the discussion at the following link, Marker.equals and Marker.hashCode don't work sometimes. For example, when the map is panned or zoomed, or it's restarted/resumed.
Add Tag / Identifier to Markers
So Marker's ID is a better key than Marker itself for a HashMap.
Map<String, MyObject> markerMap = new HashMap<String, MyObject>();
Marker marker = map.addMarker(...);
MyObject myObject = new MyObject();
markerMap.put(marker.getId(), myObject);
I think using latitude and longitude, this could be done
map.setOnMarkerClickListener(new GoogleMap.OnMarkerClickListener() {
#Override
public boolean onMarkerClick(final Marker marker) {
LatLng pos = marker.getPosition();
int arryListPosition = getArrayListPosition(pos);
return true;
}
});
and the method getArrayListPosition is
private int getArrayListPosition(LatLng pos) {
for (int i = 0; i < result.size(); i++) {
if (pos.latitude == result.get(i).getCompanyLatLng().split(",")[0]) {
if (pos.longitude == result.get(i).getCompanyLatLng()
.split(",")[1])
return i;
}
}
return 0;
}
This method will return you the position of your ArrayList who's Marker you have clicked. and you can get data from that position.
Hope it helps...
I am 4 years late to answer but I really amazed why no-one talked about marker.setTag and marker.getTag method.
As written in google API docs,
This is easier than storing a separate Map<Marker, Object>
They have introduce setTag and getTag to avoid use of Map<...>. You can use it as following way.
Marker marker = map.addMarker(...);
marker.setTag(result.get(i)); //Store your marker information here.
//To fetch your object...
map.setOnMarkerClickListener(new GoogleMap.OnMarkerClickListener() {
#Override
public boolean onMarkerClick(Marker marker) {
CustomObj obj = (CustomObj)marker.getTag();
//Your click handle event
// Pass the obj to another activity and you are done
return false;
}
});

Google maps error: Marker's position is not updated after drag

I set up a marker an set it's draggable state to true. But when I call marker.getPosition() I am always getting the same location, like marker's position is not updated after drag end.
mMap = ((MapFragment) getFragmentManager().findFragmentById(R.id.map_place))
.getMap();
LatLng MYLOCATION = new LatLng(Double.valueOf(myLat), Double.valueOf(myLng));
marker = new MarkerOptions()
.position(MYLOCATION)
.title(getString(R.string.map_title_my_location)).draggable(true);
mMap.addMarker(marker).showInfoWindow();
mMap.moveCamera(CameraUpdateFactory.newLatLngZoom(MYLOCATION, 18));
close.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
LatLng pos = marker.getPosition();
Toast.makeText(activity, "Lat: " + pos.latitude + "; Long: " + pos.longitude, Toast.LENGTH_LONG).show();
}
});
as class vars I defined:
GoogleMap mMap;
MarkerOptions marker;
Any idea?!
This is an old question but since I had the same problem myself, here's the solution: you need to set the OnMarkerDragListener for the map instance first (mMap.setOnMarkerDragListener(...)) for the markers position value to get updated. You don't really need to do anything inside the listener implementation methods (you can use marker.getPosition() anywhere you like), they just have to exist.
UPDATE
This is also documented now in https://developers.google.com/maps/documentation/android-api/marker#marker_drag_events
You can use an OnMarkerDragListener to listen for drag events on a marker. To set this listener on the map, call GoogleMap.setOnMarkerDragListener. To drag a marker, a user must long press on the marker. When the user takes their finger off the screen, the marker will stay in that position. When a marker is dragged, onMarkerDragStart(Marker) is called initially. While the marker is being dragged, onMarkerDrag(Marker) is called constantly. At the end of the drag onMarkerDragEnd(Marker) is called. You can get the position of the marker at any time by calling Marker.getPosition().
You should implement OnMarkerDragListener() in your main activity. And inside the method onMarkerDragEnd() you can get the position of your marker (by using its ID)

Categories

Resources