Android Google Maps v2: Wie füge ich einen Marker mit einem mehrzeiligen Snippet hinzu?

69

Weiß jemand, wie man dem Google Maps-Marker ein mehrzeiliges Snippet hinzufügt? Das ist mein Code zum Hinzufügen von Markern:

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

Ich möchte, dass das Snippet so aussieht:

| HEADER |
|foo     |
|bar     |

Aber wenn ich versuche, snippetText auf "foo \ n bar" zu setzen, sehe ich nur foo barund ich habe keine Ideen, wie ich es mehrzeilig machen kann. Kannst du mir helfen?

Onkel Lem
quelle

Antworten:

60

Es sieht so aus, als müssten Sie Ihre eigenen "Infofenster" -Inhalte erstellen, damit dies funktioniert:

  1. Erstellen Sie eine Implementierung InfoWindowAdapterdieser Überschreibungen, getInfoContents()um zurückzugeben, was Sie in den InfoWindowFrame aufnehmen möchten

  2. Rufen setInfoWindowAdapter()Sie an GoogleMapund übergeben Sie eine Instanz von IhnenInfoWindowAdapter

Dieses Beispielprojekt demonstriert die Technik. Das Ersetzen meiner Snippets durch "foo\nbar"korrekt verarbeitet die neue Zeile. Wahrscheinlicher ist jedoch, dass Sie nur ein Layout erstellen, das die Notwendigkeit der neuen TextViewZeile vermeidet, mit separaten Widgets für jede Zeile in den gewünschten visuellen Ergebnissen.

CommonsWare
quelle
Wenn Sie getInfoWindow () verwenden, um eine vollständig angepasste Ansicht zurückzugeben, beachten Sie, dass bei Verwendung eines RelativeLayout ein Fehler auftritt. Ich konnte meine nur zum Laufen bringen, wenn ich zu einem LinearLayout wechselte. Ich habe einen Fehlerbericht eingereicht: code.google.com/p/gmaps-api-issues/issues/detail?id=4874
Bis
@Till: Wenn Sie eine Layoutressource mit a RelativeLayoutals Root verwenden und diese aufblasen, möchten Sie normalerweise die Drei-Parameter- inflate()Methode verwenden, die im übergeordneten Element ViewGroupund falsefür die letzten beiden Parameter übergeben wird. Wir werden jedoch nicht als Eltern übergeben getInfoContents(), daher können wir das nicht tun. Ich bin zwar ein bisschen überrascht über a NullPointerException, aber ich bin überhaupt nicht überrascht, dass das RelativeLayoutnicht richtig funktioniert. Ich hätte erwartet, dass einige der Layoutregeln für die RelativeLayoutKinder des Kindes ignoriert werden oder sich auf andere Weise schlecht benehmen.
CommonsWare
@CommonsWare Ich lese das Maps V2 Chapteraus Ihrem 4.6-Buch und habe eine Frage zum Thema mit dieser Frage, daher denke ich, dass dies ein guter Ort ist, um sie zu stellen. Ich frage mich, ob es eine Möglichkeit gibt, infoWindowfür jeden Marker eine eindeutige Einstellung festzulegen, solange dies setInfoWindowAdapter()auf die Lochkarte angewendet wird.
AlexAndro
Ich habe den Code aus dem Beispielprojekt zum Laufen gebracht. Ich habe also ein benutzerdefiniertes Infofenster, bin aber nicht sicher, wie ich noch mehrere Zeilen hinzufügen soll. Ich habe zusätzliche Textansichten nach Titel und Snippet im XML-Layout hinzugefügt, aber wie kann ich Text in den neuen Textansichten anzeigen lassen?
Paul Alexander
1
@ Cbrook: Rufen Sie setText()die TextViews, nicht anders als TextViewsin einer Aktivität, Fragment, ListViewZeile, etc.
CommonsWare
130

Ich habe es auf einfachste Weise wie folgt gemacht:

private GoogleMap mMap;

Beim Hinzufügen eines Markers auf 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)));

Geben Sie anschließend den folgenden Code für den InfoWindow- Adapter in Google Map ein :

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;
    }
});

Hoffe es wird dir helfen.

Hiren Patel
quelle
2
Diese Lösung funktioniert tatsächlich. +1 zum Hinzufügen eines Codebeispiels.
MetaSnarf
1
Vielen Dank! +1 für snippet.
LinusGeffarth
1
Funktioniert hervorragend, Titel und mehrere Snippet-Zeilen! +1
Ely Dantas
2
Diese Antwort sollte wegen akzeptiert werden Code Snippet. Hat mir Zeit gespart. Auch ich mag mMapVariablennamen, weil ich das auch nicht geändert habe.
Pratik Butani
Warnung: Ich ersetze "MapsActivity.this" anstelle von mContext, um fehlerfrei ausgeführt zu werden.
Bay
15

Aufbauend auf Hiren Patels Antwort, wie Andrew S vorschlug:

 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;
        }
    });
Nublodeveloper
quelle
1

Basierend auf der Hiren Patel Lösung. Dieser Code erstellt ein TextViewfrom-Layout, nicht from zero. Ein wesentlicher Unterschied: Wenn Sie Cluster haben , wird beim Klicken auf einen Cluster keine leere Bezeichnung angezeigt.

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
quelle
0

Gleicher Code, aber 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
quelle
-1

mMap.setOnMapClickListener (neuer 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);
Karan joshi kj
quelle