74

Does anybody know how to add multiline snippet to Google Maps marker? That's my code for adding markers:

map.getMap().addMarker(new MarkerOptions()
    .position(latLng()).snippet(snippetText)
    .title(header).icon(icon));

I want snippet to look like this:

| HEADER |
|foo     |
|bar     |

but when I'm trying to set snippetText to "foo \n bar", I see just foo bar and I don't have any ideas how to make it multiline. Can you help me?

uncle Lem
  • 4,954
  • 8
  • 33
  • 53

6 Answers6

140

I have done with easiest way like below:

private GoogleMap mMap;

While adding marker on Google Map:

LatLng mLatLng = new LatLng(YourLatitude, YourLongitude);

mMap.addMarker(new MarkerOptions().position(mLatLng).title("My Title").snippet("My Snippet"+"\n"+"1st Line Text"+"\n"+"2nd Line Text"+"\n"+"3rd Line Text").icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_RED)));

After that put below code for InfoWindow adapter on Google Map:

mMap.setInfoWindowAdapter(new GoogleMap.InfoWindowAdapter() {

      @Override
      public View getInfoWindow(Marker arg0) {
         return null;
      }

      @Override
      public View getInfoContents(Marker marker) {

        LinearLayout info = new LinearLayout(mContext);
        info.setOrientation(LinearLayout.VERTICAL);

        TextView title = new TextView(mContext);
        title.setTextColor(Color.BLACK);
        title.setGravity(Gravity.CENTER);
        title.setTypeface(null, Typeface.BOLD);
        title.setText(marker.getTitle());

        TextView snippet = new TextView(mContext);
        snippet.setTextColor(Color.GRAY);
        snippet.setText(marker.getSnippet());

        info.addView(title);
        info.addView(snippet);

      return info;
    }
});

Hope it will help you.

Hiren Patel
  • 52,124
  • 21
  • 173
  • 151
  • 2
    This should be accepted answer because of `Code Snippet`. Saved my time. even I like `mMap` variable name because that also I haven't changed. – Pratik Butani Dec 15 '18 at 06:30
  • Warning: I replace "MapsActivity.this" instead of mContext to run with no error. – Bay Oct 24 '19 at 10:58
62

It looks like you will need to create your own "info window" contents to make that work:

  1. Create an implementation of InfoWindowAdapter that overrides getInfoContents() to return what you want to go into the InfoWindow frame

  2. Call setInfoWindowAdapter() on your GoogleMap, passing an instance of your InfoWindowAdapter

This sample project demonstrates the technique. Replacing my snippets with "foo\nbar" correctly processes the newline. However, more likely, you will just come up with a layout that avoids the need for the newline, with separate TextView widgets for each line in your desired visual results.

CommonsWare
  • 986,068
  • 189
  • 2,389
  • 2,491
  • If you do use getInfoWindow() to return an entirely customized view, note that there seems to be a bug when using a RelativeLayout for it. I could only get mine to work when switching to a LinearLayout. I filed a bug report: http://code.google.com/p/gmaps-api-issues/issues/detail?id=4874 – Till - Appviewer.io Jan 30 '13 at 15:44
  • @Till: Normally, when you use a layout resource with a `RelativeLayout` as the root, when you inflate it, you want to use the three-parameter `inflate()` method, passing in the parent `ViewGroup` and `false` for the last two parameters. However, we are not passed a parent in `getInfoContents()`, so we cannot do that. While I am a bit surprised about a `NullPointerException`, I am not surprised at all that the `RelativeLayout` does not work correctly. I would have expected some of the layout rules for the `RelativeLayout`'s children to be ignored or otherwise misbehave. – CommonsWare Jan 30 '13 at 15:51
  • @CommonsWare I'm reading the `Maps V2 Chapter` from your 4.6 book and I have a question that is on topic with this question so I think is a good place to ask. I wander if is there any way to set a distinct `infoWindow` for each marker, as long as `setInfoWindowAdapter()` is applied to hole map? – AlexAndro Mar 11 '13 at 08:37
  • I've got the code from the sample project working. so I have a custom infowindow but I am stuck on how to add multiple lines still. I've added in extra textviews after title and snippet in the xml layout but how do I get text to appear in the new textviews? – Paul Alexander Jan 29 '15 at 16:25
  • 1
    @cbrook: Call `setText()` on the `TextViews`, no different than `TextViews` in an activity, fragment, `ListView` row, etc. – CommonsWare Jan 29 '15 at 17:09
  • That's what I thought but it's not working for me for some reason :/ all I'm doing is putting a second textview in the xml after snippet, then identifying it and setting the text of it within getInfoContents. hmmm maybe I should start a new question? – Paul Alexander Jan 30 '15 at 09:18
15

Building on Hiren Patel's answer as Andrew S suggested:

 mMap.setInfoWindowAdapter(new GoogleMap.InfoWindowAdapter() {

        @Override
        public View getInfoWindow(Marker arg0) {
            return null;
        }

        @Override
        public View getInfoContents(Marker marker) {

            Context context = getApplicationContext(); //or getActivity(), YourActivity.this, etc.

            LinearLayout info = new LinearLayout(context);
            info.setOrientation(LinearLayout.VERTICAL);

            TextView title = new TextView(context);
            title.setTextColor(Color.BLACK);
            title.setGravity(Gravity.CENTER);
            title.setTypeface(null, Typeface.BOLD);
            title.setText(marker.getTitle());

            TextView snippet = new TextView(context);
            snippet.setTextColor(Color.GRAY);
            snippet.setText(marker.getSnippet());

            info.addView(title);
            info.addView(snippet);

            return info;
        }
    });
Community
  • 1
  • 1
Nublodeveloper
  • 1,301
  • 13
  • 20
2

Based on Hiren Patel solution. This code creates a TextView from layout, not from zero. One significant difference: if you have clusters, you won't see a void label when clicking at a cluster.

override fun onMapReady(googleMap: GoogleMap) {
    this.googleMap = googleMap
    ...

    // Use this anonymous class or implement GoogleMap.InfoWindowAdapter.
    googleMap.setInfoWindowAdapter(object : GoogleMap.InfoWindowAdapter {
        override fun getInfoContents(marker: Marker): View? {
            return null
        }

        override fun getInfoWindow(marker: Marker): View? =
            if (marker.title == null)
                null
            else {
                val inflater = LayoutInflater.from(context)
                val view = inflater.inflate(R.layout.layout_marker, null, false)
                view.label.text = marker.title
    
                view
            }
    })

layout_marker.xml:

<?xml version="1.0" encoding="utf-8"?>
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/label"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:paddingLeft="5dp"
    android:paddingRight="5dp"
    android:paddingTop="4dp"
    android:paddingBottom="4dp"
    android:textColor="$f0f0f0"
    android:textSize="12sp"
    tools:text="Marker"
    android:background="#00aaee"
    />
CoolMind
  • 26,736
  • 15
  • 188
  • 224
1

Same code, but in Kotlin:

    mMap?.setInfoWindowAdapter(object : InfoWindowAdapter {
        override fun getInfoWindow(arg0: Marker): View? {
            return null
        }
        
        override fun getInfoContents(marker: Marker): View {
            val info = LinearLayout(applicationContext)
            info.orientation = LinearLayout.VERTICAL
            val title = TextView(applicationContext)
            title.setTextColor(Color.BLACK)
            title.gravity = Gravity.CENTER
            title.setTypeface(null, Typeface.BOLD)
            title.text = marker.title
            val snippet = TextView(applicationContext)
            snippet.setTextColor(Color.GRAY)
            snippet.text = marker.snippet
            info.addView(title)
            info.addView(snippet)
            return info
        }
    })
JoeGalind
  • 3,545
  • 2
  • 29
  • 33
-1

mMap.setOnMapClickListener(new GoogleMap.OnMapClickListener() {

        @Override
        public void onMapClick(LatLng point) {

            // Already two locations
            if (markerPoints.size() > 1) {
                markerPoints.clear();
                mMap.clear();
            }

            // Adding new item to the ArrayList
            markerPoints.add(point);

            // Creating MarkerOptions
            MarkerOptions options = new MarkerOptions();

            // Setting the position of the marker

            options.position(point);
            if (markerPoints.size() == 1) {
                options.icon(BitmapDescriptorFactory.fromResource(R.mipmap.markerss)).title("Qtrip").snippet("Balance:\nEta:\nName:");
                options.getInfoWindowAnchorV();
            } else if (markerPoints.size() == 2) {
                options.icon(BitmapDescriptorFactory.fromResource(R.mipmap.markerss)).title("Qtrip").snippet("End");
            }
            mMap.setInfoWindowAdapter(new GoogleMap.InfoWindowAdapter() {

                @Override
                public View getInfoWindow(Marker arg0) {
                    return null;
                }

                @Override
                public View getInfoContents(Marker marker) {

                    Context context = getApplicationContext(); //or getActivity(), YourActivity.this, etc.

                    LinearLayout info = new LinearLayout(context);
                    info.setOrientation(LinearLayout.VERTICAL);

                    TextView title = new TextView(context);
                    title.setTextColor(Color.BLACK);
                    title.setGravity(Gravity.CENTER);
                    title.setTypeface(null, Typeface.BOLD);
                    title.setText(marker.getTitle());

                    TextView snippet = new TextView(context);
                    snippet.setTextColor(Color.GRAY);
                    snippet.setText(marker.getSnippet());

                    info.addView(title);
                    info.addView(snippet);

                    return info;
                }
            });
            mMap.addMarker(options);