Android

Android Map Utils: Show Custom Info Window View On A Marker Click

Google+ Pinterest LinkedIn Tumblr

Today, in this article, I’ll guide you through how we can show custom info window when a user clicks on a marker or inside the cluster of marker’s using the android-maps-util library. The idea of showing custom info window on a marker is to add more meaning instead of simply showing title.

Here’s the content of what we’re going to learn in this article.

Note: This assuming you have already set up Google Maps in your Android app. If not, then visit Google Maps API to get started.

Before we start looking at some code, we also need to add the following dependency in our app-level build.gradle file.

// Marker maps util dependency
implementation 'com.google.maps.android:android-maps-utils:0.5'

Now that we have all the configuration out the way, we can start showing the custom info window on a marker click.

Show simple text Title info on the marker

Once Google Maps are added to your activity or fragment, you can perform any other operations inside the getMapAsync method. Let us see the example of how to show title info on a marker.

supportMapFragment.getMapAsync(googleMap -> {
    Marker marker = googleMap.addMarker(new MarkerOptions()
                             .position(latLng)
                             .title("Your title for info")
                             .icon(BitmapDescriptorFactory
                             .fromResource(R.drawable.marker)));
})

The marker title info result is shown below.

Android Google Maps Default Marker Title Info

Show custom info window View on a marker click

In the above example, we set the default info window screen when a user clicks on a marker. But in order to customize the info window, we need to implement InfoWindowAdapter and set it via setOnInfoWindowAdapter method on a Google Maps instance.

First, let’s create a CustomMarkerInfoWindowView class which implements the InfoWindowAdapter interface.

public class CustomMarkerInfoWindowView implements GoogleMap.InfoWindowAdapter {

        private final View markerItemView;

        public CustomMarkerInfoWindowView() {
            markerItemView = layoutInflater.inflate(R.layout.marker_info_window, null);  // 1
        }

        @Override
        public View getInfoWindow(Marker marker) { // 2
            User user = (User) marker.getTag();  // 3
            if (user == null) return clusterItemView;
            TextView itemNameTextView = markerItemView.findViewById(R.id.itemNameTextView);
            TextView itemAddressTextView = markerItemView.findViewById(R.id.itemAddressTextView);
            itemNameTextView.setText(marker.getTitle());
            itemAddressTextView.setText(user.getAddress());
            return markerItemView;  // 4
        }

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

Going over the above code.

  1. In the constructor I simply inflate a view from the XML file: This is the layout that we’ll be used to show our custom info window one marker click.
  2. The getInfoWindow method will be called every time when a user clicks on a marker and provide the custom view for info window. You can check out when to use getInfoWindow and getInfoContents here on this link.
  3. The marker.getTag method returns the object associated with the specific marker. An object which can contain data about the marker representer. You can set a marker tag with the marker.setTag method after it rendered on Google Maps.
  4. Returns the info view after setting the text views.

Second, we need to do setInfoWindowAdapter on Google Maps instance.

supportMapFragment.getMapAsync( googleMap -> {
        CustomMarkerInfoWindowView markerWindowView = new CustomMarkerInfoWindowView();
        googleMap.setInfoWindowAdapter(markerWindowView);
});

After setting the info window adapter, it should look like this:

Android Google Maps Custom Info Window Marker View

Note: Only one marker info window displayed at a time. If a user clicks on another marker, the current info window will be hidden and a new one will be displayed.

Add a click listener on the marker Custom info window

Now that we’ve successfully shown our custom info window for the marker but how do we know that the user taps the info window view. Actually, there’s a utility method added inside the GoogleMap class and all we need to do is to use the setOnInfoWindowClickListener method.

Add the following code inside the getMapAsync method of your Activity or Fragment.

supportMapFragment.getMapAsync( googleMap -> {
        googleMap.setOnInfoWindowClickListener(new GoogleMap.OnInfoWindowClickListener() {
            @Override
            public void onInfoWindowClick(Marker marker) {
                     User user = (User) marker.getTag();  
                     Toast.makeText(context, user.getName(), Toast.LENGTH_SHORT).show();
                     // handle the clicked marker object 
            }
        });
});

The onInfoWindowClick method gives the marker instance of the taped item window. And we can get the User object from  the marker.getTag method.

To test the above update you need to run the application.

Android Google Maps Custom Info Window Marker With Click Listener

show custom info window marker when working with cluster’s

Showing marker info window when working with the cluster’s is a little different than the previous method. Also, I’m not going to discuss how to create markers of the cluster in this article, because I already did that in my previous article.

To show info window marker inside the cluster you must perform these following things:

supportMapFragment.getMapAsync(googleMap -> {
     ClusterManager<User> clusterManager = new ClusterManager<>(this, googleMap);  // 1
     MarkerClusterRenderer markerClusterRenderer = new MarkerClusterRenderer(this, googleMap, clusterManager); // 2
     clusterManager.setRenderer(markerClusterRenderer);
     googleMap.setInfoWindowAdapter(clusterManager.getMarkerManager());  // 3
     clusterManager.getMarkerCollection().setOnInfoWindowAdapter(new CustomMarkerInfoWindowView()); // 4
        googleMap.setOnCameraIdleListener(clusterManager);  
        googleMap.setOnMarkerClickListener(clusterManager); // 5

});

The above code does five things.

  1. To use the marker clustering utility we need to create an instance of ClusterManager.
  2. Creating a new instance of the renderer after passing the acceptable parameter. (If you’re wondering what is this “MarkerClusterRenderer” thing is, see this earlier post).
  3. Next, get the MarkerManager instance from ClusterManager and set as an info window adapter on GoogleMap.
  4. Set the CustomMarkerInfoWindowView as an info window adapter on MarkerManager.Collection instance.
  5. If we did not set the marker listener and pass the ClusterManager instance to a setOnMarkerClickListener method then you’ll not able to see the custom info window view on marker click.

If all goes well, you should be able to see the cluster manager and marker info window like this:

Android Google Maps Custom Info Window Marker With Click Listener And Cluster

I hope you enjoyed this blog on how to show a custom info window view on the marker’s click inside cluster when working with the android-maps-utils library. If you have any questions, feel free to leave them in the comments section. Also, you can get the complete source code of the above example from GitHub.

Thank you for being here and keep reading…

7 Comments

    • ahsensaeed067 Reply

      Hey Nadji,
      Yes, you can get the marker position in getInfoWindow method and then simply execute a call to the geocoder.

      Note: The geocoder request is a blocking call.

      • thanks ahsen,
        i’m use this code and it’s works

        public View getInfoWindow(Marker marker) {
        final View popup = mInflater.inflate(R.layout.info_marker_layout, null);
        double lat = marker.getPosition().latitude;
        double lng = marker.getPosition().longitude;
        Geocoder geocoder = new Geocoder(AppController.getContext(), Locale.getDefault());
        List addresses = null;
        try {
        addresses = geocoder.getFromLocation(Double.valueOf(lat), Double.valueOf(lng), 1);
        } catch (IOException e) {
        e.printStackTrace();
        }
        String alamat = addresses.get(0).getAddressLine(0);
        ((TextView) popup.findViewById(R.id.info_window)).setText(alamat);
        return popup;
        }

        • ahsensaeed067 Reply

          Hey Nadji,
          I’m glad you figure it out but the only thing I want you to change in the code is that you see you’re creating Geocoder instance every time you request for the InfoWindowView. I think you need to create a global instance of Geocoder and then reuse the same instance.

  1. ahsensaeed067 Reply

    Hey Nadji,
    Yes, you can get the marker position in getInfoWindow method and then simply execute a call to the geocoder.

    Note: The geocoder request is a blocking call.

  2. Hi Ahsen,
    Thanks for your topic.
    Is it possible to have 2 clickable buttons in each info window ?
    I know it was possible before in the older version of google map services with the deprecated methof of “.getMap()”
    but now since we use the method “.getMapAsync()” we can’t do it.
    Is there any solution ?

    • ahsensaeed067 Reply

      Hey Rami,
      Yes, it is possible to have 2 clickable buttons. Now instead of adding click listener on InfoWindow add click listener on the custom view when you finding view inside the getInfoWindow method.

Write A Comment