I'm using google's android Map Utils and below is the code I use to try to generate an info window.
/*
* Set the Google Marker Cluster Manager.
*/
mClusterManager = new ClusterManager<>(this, mGoogleMap);
mGoogleMap.setOnCameraIdleListener(mClusterManager);
mGoogleMap.setInfoWindowAdapter(mClusterManager.getMarkerManager());
mGoogleMap.setOnMarkerClickListener(mClusterManager.getMarkerManager());
mGoogleMap.setOnInfoWindowClickListener(mClusterManager);
mGoogleMap.setInfoWindowAdapter(mPlaceInfoWindowAdapter);
mGoogleMap.setOnMarkerClickListener(mClusterManager);
GoogleMap.InfoWindowAdapter infoWindowAdapter = new GoogleMap.InfoWindowAdapter()
{
#Override
public View getInfoWindow(Marker marker)
{
Toast.makeText(MainActivity.this, "getInfoWIndow", Toast.LENGTH_SHORT).show();
return null;
}
#Override
public View getInfoContents(Marker marker)
{
View v = LayoutInflater.from(MainActivity.this).inflate(R.layout.map_infowindow_layout, null);
Toast.makeText(MainActivity.this, "getInfoContents", Toast.LENGTH_SHORT).show();
return v;
}
};
mClusterManager.getMarkerCollection().setOnInfoWindowAdapter(infoWindowAdapter);
mClusterManager.getClusterMarkerCollection().setOnInfoWindowAdapter(infoWindowAdapter);
mClusterManager.setOnClusterClickListener(new ClusterManager.OnClusterClickListener<MapMarker>()
{
#Override
public boolean onClusterClick(Cluster<MapMarker> cluster)
{
Toast.makeText(MainActivity.this, "cluster click", Toast.LENGTH_SHORT).show();
return false;
}
});
mClusterManager.setOnClusterItemClickListener(new ClusterManager.OnClusterItemClickListener<MapMarker>()
{
#Override
public boolean onClusterItemClick(MapMarker mapMarker)
{
Toast.makeText(MainActivity.this, "cluster item click", Toast.LENGTH_SHORT).show();
return false;
}
});
Below is the image of the result when clicking on a marker on the map.
The methods of the InfoWindowAdapter are never called.
I've also tried to set the mGoogleMap.setOnMarkerClickListener(mClusterManager) but that doesn't work either. Am I doing something wrong or is this a bug with google's code?
I fixed this by returning false from the onClusterItemClick method. If set to true, the info window doesn't show.
Related
I am trying to center the marker's info window because it's fully visible. There are two images showing the problem. On the first the title of the info window is not visible and on the second image is how it should look like. Here is my code:
mMap.setOnMarkerClickListener(new GoogleMap.OnMarkerClickListener() {
#Override
public boolean onMarkerClick(final Marker marker) {
LatLng markerLocation = marker.getPosition();
Point mappoint = mMap.getProjection().toScreenLocation(new LatLng(markerLocation.latitude, markerLocation.longitude));
mappoint.set(mappoint.x, mappoint.y - 100);
CameraUpdate cu = CameraUpdateFactory.newLatLng(mMap.getProjection().fromScreenLocation(mappoint));
mMap.animateCamera(cu, new GoogleMap.CancelableCallback() {
#Override
public void onFinish() {
if (marker != null)
marker.showInfoWindow();
}
#Override
public void onCancel() {
}
});
return false;
}
});
The problem was the line:
returning false;
Should be:
returning true;
In my google maps fragment,
I used this to add my item as clusters
mClusterManager = new ClusterManager<ContactInfo>(getActivity(), googleMap);
mClusterManager.setOnClusterClickListener(this);
mClusterManager.addItem(myItem);
Now, I can manage to set onClusterClickListener by
mClusterManager.setOnClusterClickListener(this);
By using the above code, I can detect when I click those clusters,
However, when I click those seperate markers, this does not work.
How to detect those seperate markers I added to clusterManager?
setOnClusterClickListener is invoked when a Cluster is tapped.
You also need to set setOnClusterItemClickListener which is
Sets a callback that's invoked when an individual ClusterItem is
tapped. Note: For this listener to function, the ClusterManager must
be added as a click listener to the map.
And be sure to implement ClusterManager.OnClusterItemClickListener<T extends ClusterItem>
Try This custom Class.
private class PersonRenderer extends DefaultClusterRenderer<Person> {
public PersonRenderer() {
super(MainActivity.this, mMap, mClusterManager1);
}
#Override
protected void onBeforeClusterItemRendered(Person person, MarkerOptions markerOptions) {
Debug.e("call", "onBeforeClusterItemRendered");
// Draw a single person.
// Set the info window to show their name.
}
#Override
protected boolean shouldRenderAsCluster(Cluster<Person> cluster) {
Debug.e("call", "shouldRenderAsCluster");
return cluster.getSize() > 1;
}
#Override
protected void onClusterItemRendered(Person clusterItem, Marker marker) {
super.onClusterItemRendered(clusterItem, marker);
Debug.e("call", "onClusterItemRendered");
}
}
onClusterClick
#Override
public boolean onClusterClick(Cluster<Person> cluster) {
Debug.e("call", "onClusterClick");
// Show a toast with some info when the cluster is clicked.
String firstName = cluster.getItems().iterator().next().name;
// Toast.makeText(this, cluster.getSize() + " (including " + firstName + ")", Toast.LENGTH_SHORT).show();
// Zoom in the cluster. Need to create LatLngBounds and including all the cluster items
// inside of bounds, then animate to center of the bounds.
// Create the builder to collect all essential cluster items for the bounds.
LatLngBounds.Builder builder = LatLngBounds.builder();
for (ClusterItem item : cluster.getItems()) {
builder.include(item.getPosition());
}
// Get the LatLngBounds
final LatLngBounds bounds = builder.build();
// Animate camera to the bounds
try {
mMap.animateCamera(CameraUpdateFactory.newLatLngBounds(bounds, 100));
} catch (Exception e) {
e.printStackTrace();
}
return true;
}
onClusterInfoWindowClick
#Override
public void onClusterInfoWindowClick(Cluster<Person> cluster) {
Debug.e("call", "onClusterInfoWindowClick");
// Does nothing, but you could go to a list of the users.
// clickedCluster = cluster;
}
onClusterItemClick
#Override
public boolean onClusterItemClick(Person item) {
// Does nothing, but you could go into the user's profile page, for example.
Debug.e("call", "onClusterItemClick");
clickedClusterItem = item;
return false;
}
onClusterItemInfoWindowClick
#Override
public void onClusterItemInfoWindowClick(Person item) {
// Does nothing, but you could go into the user's profile page, for example.
Debug.e("call", "onClusterItemInfoWindowClick");
}
I want to call some activity by clicking on one button inside info view adapter of marker of google map. is this possible, then how?
My code is like that
// Info view adapter
googleMap.setInfoWindowAdapter(new InfoWindowAdapter() {
#Override
public View getInfoWindow(Marker marker) {
view = ((Activity) context).getLayoutInflater().inflate(R.layout.row_browse_jobs_map,null);
txtDate = (TextView) view.findViewById(R.id.txt_browse_jobMap_placed_date);
String j_date = "25 JAN, 2015";
//click listener for button
txtDate.setOnClickListener(new OnClickListener() {
public void onClick(View arg0) {
Toast.makeText(context, "clicked", Toast.LENGTH_SHORT).show();
}
});
return view;
}
//content wraping
public View getInfoContents(Marker arg0) {
return null;
}
});
Please check this. I didn't tried this. so i am not sure this is correct or not.
public View getInfoContents(Marker arg0) {
googleMap.setOnInfoWindowClickListener(new OnInfoWindowClickListener() {
public void onInfoWindowClick(Marker marker) {
//your code
}
}
//your remaining code
}
Refer this set InfoWindowAdapter show information only for first marker clicked
Hi i working on demo application for google map with custom pop-up.
please suggest me how to handle textview & image view click handle.
i can't get event. below are my code.
class PopupAdapter implements InfoWindowAdapter {
LayoutInflater inflater=null;
Context context;
PopupAdapter(LayoutInflater inflater, Context context) {
this.inflater=inflater;
this.context = context;
}
public View getInfoWindow(Marker marker) {
return(null);
}
public View getInfoContents(Marker marker) {
MyModel mapItem = (MyModel) MainActivity.markers.get(marker.getId());
View popup=inflater.inflate(R.layout.popup, null);
TextView tv=(TextView)popup.findViewById(R.id.title);
ImageView im = (ImageView)popup.findViewById(R.id.icon);
tv.setText(marker.getTitle());
tv=(TextView)popup.findViewById(R.id.snippet);
tv.setText(marker.getSnippet());
im.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
Log.e("POPUP", "Image Click");
}
});
tv.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
Log.e("POPUP", "HI");
Toast.makeText(context, "HI", Toast.LENGTH_SHORT).show();
}
});
return(popup);
}
}
Main Activity
public class MainActivity extends AbstractMapActivity implements
OnNavigationListener, OnInfoWindowClickListener {
private static final String STATE_NAV="nav";
private static final int[] MAP_TYPE_NAMES= { R.string.normal,
R.string.hybrid, R.string.satellite, R.string.terrain };
private static final int[] MAP_TYPES= { GoogleMap.MAP_TYPE_NORMAL,
GoogleMap.MAP_TYPE_HYBRID, GoogleMap.MAP_TYPE_SATELLITE,
GoogleMap.MAP_TYPE_TERRAIN };
private GoogleMap map=null;
public static HashMap<String, MyModel> markers= new HashMap<String, MyModel>();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (readyToGo()) {
setContentView(R.layout.activity_main);
SupportMapFragment mapFrag=
(SupportMapFragment)getSupportFragmentManager().findFragmentById(R.id.map);
initListNav();
map=mapFrag.getMap();
if (savedInstanceState == null) {
CameraUpdate center=
CameraUpdateFactory.newLatLng(new LatLng(40.76793169992044,
-73.98180484771729));
CameraUpdate zoom=CameraUpdateFactory.zoomTo(15);
map.moveCamera(center);
map.animateCamera(zoom);
}
MyModel item = new MyModel();
item.setId("1");
item.setName("Bhavesh");
item.setAdd("Krishnanagar");
addMarker(map, 40.748963847316034, -73.96807193756104,R.string.un, R.string.united_nations,item);
item = new MyModel();
item.setId("2");
item.setName("Kunal");
item.setAdd("Bhavnagar");
addMarker(map, 40.76866299974387, -73.98268461227417,R.string.lincoln_center,R.string.lincoln_center_snippet,item);
item = new MyModel();
item.setId("3");
item.setName("Ravi");
item.setAdd("Ahmedabad");
addMarker(map, 40.765136435316755, -73.97989511489868,R.string.carnegie_hall, R.string.practice_x3,item);
item = new MyModel();
item.setId("3");
item.setName("Binitbhai");
item.setAdd("Shivranjani");
addMarker(map, 40.70686417491799, -74.01572942733765,R.string.downtown_club, R.string.heisman_trophy,item);
map.setInfoWindowAdapter(new PopupAdapter(getLayoutInflater(),MainActivity.this));
map.setOnInfoWindowClickListener(this);
}
}
#Override
public boolean onNavigationItemSelected(int itemPosition, long itemId) {
map.setMapType(MAP_TYPES[itemPosition]);
return(true);
}
#Override
public void onSaveInstanceState(Bundle savedInstanceState) {
super.onSaveInstanceState(savedInstanceState);
savedInstanceState.putInt(STATE_NAV, getSupportActionBar().getSelectedNavigationIndex());
}
#Override
public void onRestoreInstanceState(Bundle savedInstanceState) {
super.onRestoreInstanceState(savedInstanceState);
getSupportActionBar().setSelectedNavigationItem(savedInstanceState.getInt(STATE_NAV));
}
#Override
public void onInfoWindowClick(Marker marker) {
// MyModel mapItem = (MyModel) markers.get(marker.getId());
// Toast.makeText(this,marker.getSnippet()+ marker.getTitle() + " "+mapItem.getName() +" "+mapItem.getAdd() , Toast.LENGTH_LONG).show();
}
private void initListNav() {
ArrayList<String> items=new ArrayList<String>();
ArrayAdapter<String> nav=null;
ActionBar bar=getSupportActionBar();
for (int type : MAP_TYPE_NAMES) {
items.add(getString(type));
}
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH) {
nav=
new ArrayAdapter<String>(
bar.getThemedContext(),
android.R.layout.simple_spinner_item,
items);
}
else {
nav=
new ArrayAdapter<String>(
this,
android.R.layout.simple_spinner_item,
items);
}
nav.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
bar.setNavigationMode(ActionBar.NAVIGATION_MODE_LIST);
bar.setListNavigationCallbacks(nav, this);
}
private void addMarker(GoogleMap map, double lat, double lon, int title, int snippet,MyModel item) {
markers.put(map.addMarker(new MarkerOptions().position(new LatLng(lat, lon)).title(getString(title)).snippet(getString(snippet)).icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_AZURE))).getId(), item);
// map.addMarker(new MarkerOptions().position(new LatLng(lat, lon)).title(getString(title)).snippet(getString(snippet)).icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_AZURE)));
}
}
Please suggest me how to do this event.
thank you..
You cannot put OnClickListeners on the contents of an info window. The info window itself is not displaying your layout, but rather a Bitmap generated from the layout. This is covered in the documentation:
As mentioned in the previous section on info windows, an info window is not a live View, rather the view is rendered as an image onto the map. As a result, any listeners you set on the view are disregarded and you cannot distinguish between click events on various parts of the view. You are advised not to place interactive components — such as buttons, checkboxes, or text inputs — within your custom info window.
You can use setOnInfoWindowClickListener() to find out when the info window itself is tapped.
As explained in other answers what you want to achieve is not supported directly by Google Maps Android API v2, but...
you can do what you need by putting yourself in front of MapFragment or MapView, handle MotionEvents to make your OnClickListeners be called.
See this answer for a nice (but hackish) how-to: https://stackoverflow.com/a/15040761/2183804
yes you cannot add listener on the view of info window. One thing you can do , onInfoWindowClick show alert menu and give the user some options.
mMap.setOnInfoWindowClickListener(new OnInfoWindowClickListener() {
#Override
public void onInfoWindowClick(Marker arg0) {
final CharSequence[] items = { "message", "call"};
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setTitle("Call");
builder.setItems(items, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int item) {
if (item == 0) {
sendMessage();
} else {
makeCall();
}
}
});
AlertDialog alert = builder.create();
alert.show();
}
});
Or you can try something like this..
I am not sure whether its work or not.
https://stackoverflow.com/a/15040761/1792228
So, I have set infowindowadapter for my Google map, but the problem is that when I click on the first marker, it shows the information correctly, but when I hit the second marker it shows information from the first one, so infowindowadapter doesn't refresh.
Can someone tell me why that it and how to fix it?
I was following this post to set infowindowadapter:
custom info window adapter with custom data in map v2
EDIT:
new getMarkers().execute();
mMap.setOnMarkerClickListener(new OnMarkerClickListener() {
#Override
public boolean onMarkerClick(Marker marker) {
marker.showInfoWindow();
return false;
}
});
mMap.setInfoWindowAdapter(new InfoWindowAdapter() {
#Override
public View getInfoWindow(Marker marker) {
// TODO Auto-generated method stub
return null;
}
#Override
public View getInfoContents(Marker marker) {
View view = getLayoutInflater().inflate(R.layout.post_details_on_map,null);
date = (TextView)view.findViewById(R.id.txtMarkerDate);
comment = (TextView)view.findViewById(R.id.txtMarkerComment);
image = (ImageView)view.findViewById(R.id.ivMarkerPicture);
MyMarkerInfo mmi = markerMap.get(marker.getId());
List<NameValuePair> params = new ArrayList<NameValuePair>();
params.add(new BasicNameValuePair("id",mmi.getId()));
MarkerDetails mDetails = new JSONAdapter().getMarkerDetails(params);
date.setText(mDetails.getDate());
comment.setText(mDetails.getComment());
new getPicture().execute(mDetails.getImageUrl());
return view;
}
});
}
Here is my code for exactly the same operation:
// Setting a custom info window adapter for the google map
map.setInfoWindowAdapter(new InfoWindowAdapter() {
// Use default InfoWindow frame
#Override
public View getInfoWindow(Marker args) {
return null;
}
// Defines the contents of the InfoWindow
#Override
public View getInfoContents(Marker args) {
// Getting view from the layout file info_window_layout
View v = getLayoutInflater().inflate(R.layout.info_window_layout, null);
// Getting the position from the marker
clickMarkerLatLng = args.getPosition();
TextView title = (TextView) v.findViewById(R.id.tvTitle);
title.setText(args.getTitle());
map.setOnInfoWindowClickListener(new OnInfoWindowClickListener() {
public void onInfoWindowClick(Marker marker)
{
if (SGTasksListAppObj.getInstance().currentUserLocation!=null)
{
if (String.valueOf(SGTasksListAppObj.getInstance().currentUserLocation.getLatitude()).substring(0, 8).contains(String.valueOf(clickMarkerLatLng.latitude).substring(0, 8)) &&
String.valueOf(SGTasksListAppObj.getInstance().currentUserLocation.getLongitude()).substring(0, 8).contains(String.valueOf(clickMarkerLatLng.longitude).substring(0, 8)))
{
Toast.makeText(getApplicationContext(), "This your current location, navigation is not needed.", Toast.LENGTH_SHORT).show();
}
else
{
FlurryAgent.onEvent("Start navigation window was clicked from daily map");
tasksRepository = SGTasksListAppObj.getInstance().tasksRepository.getTasksRepository();
for (Task tmptask : tasksRepository)
{
String tempTaskLat = String.valueOf(tmptask.getLatitude());
String tempTaskLng = String.valueOf(tmptask.getLongtitude());
Log.d(TAG, String.valueOf(tmptask.getLatitude())+","+String.valueOf(clickMarkerLatLng.latitude).substring(0, 8));
if (tempTaskLat.contains(String.valueOf(clickMarkerLatLng.latitude).substring(0, 8)) && tempTaskLng.contains(String.valueOf(clickMarkerLatLng.longitude).substring(0, 8)))
{
task = tmptask;
break;
}
}
/*
findDirections(SGTasksListAppObj.getInstance().currentUserLocation.getLatitude(),
SGTasksListAppObj.getInstance().currentUserLocation.getLongitude(),
clickMarkerLatLng.latitude, clickMarkerLatLng.longitude, GMapV2Direction.MODE_DRIVING );
*/
Intent intent = new Intent(getApplicationContext() ,RoadDirectionsActivity.class);
intent.putExtra(TasksListActivity.KEY_ID, task.getId());
startActivity(intent);
}
}
else
{
Toast.makeText(getApplicationContext(), "Your current location could not be found,\nNavigation is not possible.", Toast.LENGTH_SHORT).show();
}
}
});
// Returning the view containing InfoWindow contents
return v;
}
});
My guess would be that your are getting other markers information the wrong way. try to compare between my method and yours, and try to log the process to see that you are passing the right Id and getting the right info.