J'essaie de personnaliser InfoWindow
après un clic sur un marqueur avec la nouvelle API Google Maps v2. Je veux que cela ressemble à l'application de cartes d'origine de Google. Comme ça:
Quand j'ai à l' ImageButton
intérieur, cela ne fonctionne pas - l'ensemble InfoWindow
est sélectionné et pas seulement le ImageButton
. J'ai lu que c'est parce qu'il n'y a pas de View
lui - même mais que c'est un instantané, de sorte que les éléments individuels ne peuvent pas être distingués les uns des autres.
EDIT: Dans la documentation (grâce à Disco S2 ):
Comme mentionné dans la section précédente sur les fenêtres d'informations, une fenêtre d'informations n'est pas une vue en direct, mais la vue est rendue sous forme d'image sur la carte. Par conséquent, tous les écouteurs que vous définissez dans la vue sont ignorés et vous ne pouvez pas faire la distinction entre les événements de clic sur différentes parties de la vue. Il est conseillé de ne pas placer de composants interactifs - tels que des boutons, des cases à cocher ou des entrées de texte - dans votre fenêtre d'informations personnalisée.
Mais si Google l'utilise, il doit y avoir un moyen de le faire. Est-ce que quelqu'un a une idée?
la source
View.draw(Canvas)
) ... Cela signifie que les modifications ultérieures de la vue ne seront pas reflétées par la fenêtre d'informations sur la carte. Pour mettre à jour la fenêtre d'informations ultérieurement En outre, la fenêtre d'informations ne respectera aucune des interactivités typiques d'une vue normale comme les événements tactiles ou gestuels. Cependant, vous pouvez écouter un événement de clic générique sur toute la fenêtre d'informations comme décrit dans la section ci-dessous. ... dans votre exemple n'est que textviewRéponses:
Je cherchais moi-même une solution à ce problème sans succès, j'ai donc dû lancer la mienne que j'aimerais partager ici avec vous. (Veuillez excuser mon mauvais anglais) (C'est un peu fou de répondre à un autre tchèque en anglais :-))
La première chose que j'ai essayé a été d'utiliser un bon vieux
PopupWindow
. C'est assez simple - il suffit d'écouterOnMarkerClickListener
et d'afficher une personnalisationPopupWindow
au-dessus du marqueur. Certains autres gars ici sur StackOverflow ont suggéré cette solution et cela semble plutôt bon à première vue. Mais le problème avec cette solution apparaît lorsque vous commencez à déplacer la carte. Vous devez déplacerPopupWindow
vous-même d'une manière ou d'une autre, ce qui est possible (en écoutant certains événements onTouch), mais à mon humble avis, vous ne pouvez pas le faire paraître assez bien, en particulier sur certains appareils lents. Si vous le faites de la manière simple, il "saute" d'un endroit à un autre. Vous pouvez également utiliser des animations pour peaufiner ces sauts, mais de cette façon, il yPopupWindow
aura toujours "un pas en arrière" là où il devrait être sur la carte, ce que je n'aime tout simplement pas.À ce stade, je réfléchissais à une autre solution. J'ai réalisé que je n'avais pas vraiment besoin de beaucoup de liberté - pour montrer mes vues personnalisées avec toutes les possibilités qui vont avec (comme des barres de progression animées, etc.). Je pense qu'il y a une bonne raison pour laquelle même les ingénieurs Google ne le font pas de cette façon dans l'application Google Maps. Tout ce dont j'ai besoin est un bouton ou deux sur l'InfoWindow qui affichera un état enfoncé et déclenchera certaines actions lorsque vous cliquez dessus. J'ai donc proposé une autre solution qui se divise en deux parties:
Première partie:
La première partie est de pouvoir attraper les clics sur les boutons pour déclencher une action. Mon idée est la suivante:
MapFragment
(ouMapView
) dans un ViewGroup personnalisé (le mien s'appelle MapWrapperLayout)MapWrapperLayout
dispatchTouchEvent de et (si l'InfoWindow est actuellement affiché) acheminez d'abord les MotionEvents vers l'InfoWindow créée précédemment. S'il ne consomme pas les MotionEvents (par exemple, parce que vous n'avez cliqué sur aucune zone cliquable dans InfoWindow, etc.) alors (et seulement alors) laissez les événements descendre à la superclasse de MapWrapperLayout afin qu'il soit finalement livré à la carte.Voici le code source de MapWrapperLayout:
package com.circlegate.tt.cg.an.lib.map; import com.google.android.gms.maps.GoogleMap; import com.google.android.gms.maps.model.Marker; import android.content.Context; import android.graphics.Point; import android.util.AttributeSet; import android.view.MotionEvent; import android.view.View; import android.widget.RelativeLayout; public class MapWrapperLayout extends RelativeLayout { /** * Reference to a GoogleMap object */ private GoogleMap map; /** * Vertical offset in pixels between the bottom edge of our InfoWindow * and the marker position (by default it's bottom edge too). * It's a good idea to use custom markers and also the InfoWindow frame, * because we probably can't rely on the sizes of the default marker and frame. */ private int bottomOffsetPixels; /** * A currently selected marker */ private Marker marker; /** * Our custom view which is returned from either the InfoWindowAdapter.getInfoContents * or InfoWindowAdapter.getInfoWindow */ private View infoWindow; public MapWrapperLayout(Context context) { super(context); } public MapWrapperLayout(Context context, AttributeSet attrs) { super(context, attrs); } public MapWrapperLayout(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); } /** * Must be called before we can route the touch events */ public void init(GoogleMap map, int bottomOffsetPixels) { this.map = map; this.bottomOffsetPixels = bottomOffsetPixels; } /** * Best to be called from either the InfoWindowAdapter.getInfoContents * or InfoWindowAdapter.getInfoWindow. */ public void setMarkerWithInfoWindow(Marker marker, View infoWindow) { this.marker = marker; this.infoWindow = infoWindow; } @Override public boolean dispatchTouchEvent(MotionEvent ev) { boolean ret = false; // Make sure that the infoWindow is shown and we have all the needed references if (marker != null && marker.isInfoWindowShown() && map != null && infoWindow != null) { // Get a marker position on the screen Point point = map.getProjection().toScreenLocation(marker.getPosition()); // Make a copy of the MotionEvent and adjust it's location // so it is relative to the infoWindow left top corner MotionEvent copyEv = MotionEvent.obtain(ev); copyEv.offsetLocation( -point.x + (infoWindow.getWidth() / 2), -point.y + infoWindow.getHeight() + bottomOffsetPixels); // Dispatch the adjusted MotionEvent to the infoWindow ret = infoWindow.dispatchTouchEvent(copyEv); } // If the infoWindow consumed the touch event, then just return true. // Otherwise pass this event to the super class and return it's result return ret || super.dispatchTouchEvent(ev); } }
Tout cela rendra les vues à l'intérieur de l'InfoView "live" à nouveau - les OnClickListeners commenceront à se déclencher, etc.
Deuxième partie: le problème restant est que, de toute évidence, vous ne pouvez pas voir les modifications de l'interface utilisateur de votre InfoWindow à l'écran. Pour ce faire, vous devez appeler manuellement Marker.showInfoWindow. Maintenant, si vous effectuez un changement permanent dans votre InfoWindow (comme changer le libellé de votre bouton pour quelque chose d'autre), cela suffit.
Mais montrer l'état d'un bouton enfoncé ou quelque chose de cette nature est plus compliqué. Le premier problème est que (au moins) je n'ai pas pu faire en sorte que InfoWindow affiche l'état normal du bouton enfoncé. Même si j'ai appuyé sur le bouton pendant un long moment, il est juste resté non appuyé sur l'écran. Je pense que c'est quelque chose qui est géré par le cadre de la carte lui-même, ce qui garantit probablement de ne pas afficher d'état transitoire dans les fenêtres d'informations. Mais je peux me tromper, je n'ai pas essayé de le découvrir.
Ce que j'ai fait est un autre hack désagréable - j'ai attaché un
OnTouchListener
au bouton et changé manuellement son arrière-plan lorsque le bouton a été enfoncé ou relâché sur deux dessinables personnalisés - l'un avec un bouton dans un état normal et l'autre dans un état enfoncé. Ce n'est pas très agréable, mais ça marche :). Maintenant, j'ai pu voir le bouton basculer entre les états normal et pressé à l'écran.Il y a encore un dernier problème - si vous cliquez sur le bouton trop rapidement, il ne montre pas l'état enfoncé - il reste juste dans son état normal (bien que le clic lui-même soit déclenché donc le bouton "fonctionne"). Au moins, c'est ainsi que cela apparaît sur mon Galaxy Nexus. Donc, la dernière chose que j'ai faite, c'est que j'ai retardé un peu le bouton dans son état enfoncé. C'est aussi assez moche et je ne sais pas comment cela fonctionnerait sur certains appareils plus anciens et lents, mais je soupçonne que même le cadre de la carte lui-même fait quelque chose comme ça. Vous pouvez l'essayer vous-même - lorsque vous cliquez sur toute l'InfoWindow, il reste dans un état enfoncé un peu plus longtemps, puis les boutons normaux le font (encore une fois - au moins sur mon téléphone). Et c'est en fait ainsi que cela fonctionne même sur l'application originale Google Maps.
Quoi qu'il en soit, je me suis écrit une classe personnalisée qui gère les changements d'état des boutons et toutes les autres choses que j'ai mentionnées, voici donc le code:
package com.circlegate.tt.cg.an.lib.map; import android.graphics.drawable.Drawable; import android.os.Handler; import android.view.MotionEvent; import android.view.View; import android.view.View.OnTouchListener; import com.google.android.gms.maps.model.Marker; public abstract class OnInfoWindowElemTouchListener implements OnTouchListener { private final View view; private final Drawable bgDrawableNormal; private final Drawable bgDrawablePressed; private final Handler handler = new Handler(); private Marker marker; private boolean pressed = false; public OnInfoWindowElemTouchListener(View view, Drawable bgDrawableNormal, Drawable bgDrawablePressed) { this.view = view; this.bgDrawableNormal = bgDrawableNormal; this.bgDrawablePressed = bgDrawablePressed; } public void setMarker(Marker marker) { this.marker = marker; } @Override public boolean onTouch(View vv, MotionEvent event) { if (0 <= event.getX() && event.getX() <= view.getWidth() && 0 <= event.getY() && event.getY() <= view.getHeight()) { switch (event.getActionMasked()) { case MotionEvent.ACTION_DOWN: startPress(); break; // We need to delay releasing of the view a little so it shows the pressed state on the screen case MotionEvent.ACTION_UP: handler.postDelayed(confirmClickRunnable, 150); break; case MotionEvent.ACTION_CANCEL: endPress(); break; default: break; } } else { // If the touch goes outside of the view's area // (like when moving finger out of the pressed button) // just release the press endPress(); } return false; } private void startPress() { if (!pressed) { pressed = true; handler.removeCallbacks(confirmClickRunnable); view.setBackground(bgDrawablePressed); if (marker != null) marker.showInfoWindow(); } } private boolean endPress() { if (pressed) { this.pressed = false; handler.removeCallbacks(confirmClickRunnable); view.setBackground(bgDrawableNormal); if (marker != null) marker.showInfoWindow(); return true; } else return false; } private final Runnable confirmClickRunnable = new Runnable() { public void run() { if (endPress()) { onClickConfirmed(view, marker); } } }; /** * This is called after a successful click */ protected abstract void onClickConfirmed(View v, Marker marker); }
Voici un fichier de mise en page InfoWindow personnalisé que j'ai utilisé:
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="wrap_content" android:layout_height="wrap_content" android:gravity="center_vertical" > <LinearLayout android:layout_width="wrap_content" android:layout_height="wrap_content" android:orientation="vertical" android:layout_marginRight="10dp" > <TextView android:id="@+id/title" android:layout_width="wrap_content" android:layout_height="wrap_content" android:textSize="18sp" android:text="Title" /> <TextView android:id="@+id/snippet" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="snippet" /> </LinearLayout> <Button android:id="@+id/button" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Button" /> </LinearLayout>
Fichier de mise en page de l'activité de test (se
MapFragment
trouvant à l'intérieur duMapWrapperLayout
):<com.circlegate.tt.cg.an.lib.map.MapWrapperLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:id="@+id/map_relative_layout" android:layout_width="match_parent" android:layout_height="match_parent" tools:context=".MainActivity" > <fragment android:id="@+id/map" android:layout_width="match_parent" android:layout_height="match_parent" class="com.google.android.gms.maps.MapFragment" /> </com.circlegate.tt.cg.an.lib.map.MapWrapperLayout>
Et enfin le code source d'une activité de test, qui rassemble tout cela:
package com.circlegate.testapp; import com.circlegate.tt.cg.an.lib.map.MapWrapperLayout; import com.circlegate.tt.cg.an.lib.map.OnInfoWindowElemTouchListener; import com.google.android.gms.maps.GoogleMap; import com.google.android.gms.maps.GoogleMap.InfoWindowAdapter; import com.google.android.gms.maps.MapFragment; import com.google.android.gms.maps.model.LatLng; import com.google.android.gms.maps.model.Marker; import com.google.android.gms.maps.model.MarkerOptions; import android.os.Bundle; import android.app.Activity; import android.content.Context; import android.view.View; import android.view.ViewGroup; import android.widget.Button; import android.widget.TextView; import android.widget.Toast; public class MainActivity extends Activity { private ViewGroup infoWindow; private TextView infoTitle; private TextView infoSnippet; private Button infoButton; private OnInfoWindowElemTouchListener infoButtonListener; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); final MapFragment mapFragment = (MapFragment)getFragmentManager().findFragmentById(R.id.map); final MapWrapperLayout mapWrapperLayout = (MapWrapperLayout)findViewById(R.id.map_relative_layout); final GoogleMap map = mapFragment.getMap(); // MapWrapperLayout initialization // 39 - default marker height // 20 - offset between the default InfoWindow bottom edge and it's content bottom edge mapWrapperLayout.init(map, getPixelsFromDp(this, 39 + 20)); // We want to reuse the info window for all the markers, // so let's create only one class member instance this.infoWindow = (ViewGroup)getLayoutInflater().inflate(R.layout.info_window, null); this.infoTitle = (TextView)infoWindow.findViewById(R.id.title); this.infoSnippet = (TextView)infoWindow.findViewById(R.id.snippet); this.infoButton = (Button)infoWindow.findViewById(R.id.button); // Setting custom OnTouchListener which deals with the pressed state // so it shows up this.infoButtonListener = new OnInfoWindowElemTouchListener(infoButton, getResources().getDrawable(R.drawable.btn_default_normal_holo_light), getResources().getDrawable(R.drawable.btn_default_pressed_holo_light)) { @Override protected void onClickConfirmed(View v, Marker marker) { // Here we can perform some action triggered after clicking the button Toast.makeText(MainActivity.this, marker.getTitle() + "'s button clicked!", Toast.LENGTH_SHORT).show(); } }; this.infoButton.setOnTouchListener(infoButtonListener); map.setInfoWindowAdapter(new InfoWindowAdapter() { @Override public View getInfoWindow(Marker marker) { return null; } @Override public View getInfoContents(Marker marker) { // Setting up the infoWindow with current's marker info infoTitle.setText(marker.getTitle()); infoSnippet.setText(marker.getSnippet()); infoButtonListener.setMarker(marker); // We must call this to set the current marker and infoWindow references // to the MapWrapperLayout mapWrapperLayout.setMarkerWithInfoWindow(marker, infoWindow); return infoWindow; } }); // Let's add a couple of markers map.addMarker(new MarkerOptions() .title("Prague") .snippet("Czech Republic") .position(new LatLng(50.08, 14.43))); map.addMarker(new MarkerOptions() .title("Paris") .snippet("France") .position(new LatLng(48.86,2.33))); map.addMarker(new MarkerOptions() .title("London") .snippet("United Kingdom") .position(new LatLng(51.51,-0.1))); } public static int getPixelsFromDp(Context context, float dp) { final float scale = context.getResources().getDisplayMetrics().density; return (int)(dp * scale + 0.5f); } }
C'est ça. Jusqu'à présent, je n'ai testé cela que sur mon Galaxy Nexus (4.2.1) et Nexus 7 (également 4.2.1), je vais l'essayer sur un téléphone Gingerbread lorsque j'en aurai l'occasion. Une limitation que j'ai trouvée jusqu'à présent est que vous ne pouvez pas faire glisser la carte d'où se trouve votre bouton à l'écran et déplacer la carte. Cela pourrait probablement être surmonté d'une manière ou d'une autre, mais pour l'instant, je peux vivre avec ça.
Je sais que c'est un truc moche mais je n'ai rien trouvé de mieux et j'ai tellement besoin de ce modèle de conception que ce serait vraiment une raison de revenir au framework map v1 (ce que j'aimerais vraiment éviter pour une nouvelle application avec des fragments, etc.). Je ne comprends tout simplement pas pourquoi Google n'offre pas aux développeurs un moyen officiel d'avoir un bouton sur InfoWindows. C'est un modèle de conception si courant, de plus, ce modèle est utilisé même dans l'application officielle Google Maps :). Je comprends les raisons pour lesquelles ils ne peuvent pas simplement faire "vivre" vos vues dans InfoWindows - cela tuerait probablement les performances lors du déplacement et du défilement de la carte. Mais il devrait y avoir un moyen d'obtenir cet effet sans utiliser de vues.
la source
view.setBackground(bgDrawablePressed);
parif (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN) { view.setBackgroundDrawable(bgDrawablePressed); }else{ view.setBackground(bgDrawablePressed); }
pour fonctionner dans Android Gingerbread, Remarque: il existe une autre occurrence deview.setBackground
dans le code.Je vois que cette question est déjà ancienne mais quand même ...
Nous avons créé une bibliothèque sipmle dans notre entreprise pour réaliser ce qui est souhaité - Une fenêtre d'information interactive avec des vues et tout. Vous pouvez le vérifier sur github .
J'espère que cela aide :)
la source
Voici mon point de vue sur le problème. Je crée une
AbsoluteLayout
superposition qui contient une fenêtre d'informations (une vue régulière avec toutes les capacités d'interactivité et de dessin). Ensuite, je commenceHandler
ce qui synchronise la position de la fenêtre d'information avec la position du point sur la carte toutes les 16 ms. Cela semble fou, mais fonctionne réellement.Vidéo de démonstration: https://www.youtube.com/watch?v=bT9RpH4p9mU (tenez compte du fait que les performances sont diminuées en raison de l'émulateur et de l'enregistrement vidéo exécutés simultanément).
Code de la démo: https://github.com/deville/info-window-demo
Un article fournissant des détails (en russe): http://habrahabr.ru/post/213415/
la source
Pour ceux qui n'ont pas pu obtenir de
choose007's
réponse opérationnelleSi
clickListener
ne fonctionne pas correctement à tout moment dans lachose007's
solution, essayez de mettre en œuvre à laView.onTouchListener
place declickListener
. Gérez l'événement tactile en utilisant l'une des actionsACTION_UP
ouACTION_DOWN
. Pour une raison quelconque, les cartesinfoWindow
provoquent un comportement étrange lors de la distribution versclickListeners
.infoWindow.findViewById(R.id.my_view).setOnTouchListener(new View.OnTouchListener() { @Override public boolean onTouch(View v, MotionEvent event) { int action = MotionEventCompat.getActionMasked(event); switch (action){ case MotionEvent.ACTION_UP: Log.d(TAG,"a view in info window clicked" ); break; } return true; }
Edit: Voici comment je l'ai fait étape par étape
Commencez par gonfler votre propre infowindow (variable globale) quelque part dans votre activité / fragment. Le mien est dans le fragment. Assurez-vous également que la vue racine dans votre disposition d'infowindow est linéaire (pour une raison quelconque, la disposition relative prenait toute la largeur de l'écran dans l'infowindow)
infoWindow = (ViewGroup) getActivity().getLayoutInflater().inflate(R.layout.info_window, null); /* Other global variables used in below code*/ private HashMap<Marker,YourData> mMarkerYourDataHashMap = new HashMap<>(); private GoogleMap mMap; private MapWrapperLayout mapWrapperLayout;
Ensuite, dans le rappel onMapReady de l'api android de google maps (suivez ceci si vous ne savez pas ce qu'est onMapReady Maps> Documentation - Mise en route )
@Override public void onMapReady(GoogleMap googleMap) { /*mMap is global GoogleMap variable in activity/fragment*/ mMap = googleMap; /*Some function to set map UI settings*/ setYourMapSettings();
MapWrapperLayout
initialisation http://stackoverflow.com/questions/14123243/google-maps-android-api-v2- interactive-infowindow-like-in-original-android-go / 15040761 # 15040761 39 - hauteur du marqueur par défaut 20 - décalage entre les bord inférieur par défaut d'InfoWindow et bord inférieur de son contenu * /mapWrapperLayout.init(mMap, Utils.getPixelsFromDp(mContext, 39 + 20)); /*handle marker clicks separately - not necessary*/ mMap.setOnMarkerClickListener(this); mMap.setInfoWindowAdapter(new GoogleMap.InfoWindowAdapter() { @Override public View getInfoWindow(Marker marker) { return null; } @Override public View getInfoContents(Marker marker) { YourData data = mMarkerYourDataHashMap.get(marker); setInfoWindow(marker,data); mapWrapperLayout.setMarkerWithInfoWindow(marker, infoWindow); return infoWindow; } }); }
Méthode SetInfoWindow
private void setInfoWindow (final Marker marker, YourData data) throws NullPointerException{ if (data.getVehicleNumber()!=null) { ((TextView) infoWindow.findViewById(R.id.VehicelNo)) .setText(data.getDeviceId().toString()); } if (data.getSpeed()!=null) { ((TextView) infoWindow.findViewById(R.id.txtSpeed)) .setText(data.getSpeed()); } //handle dispatched touch event for view click infoWindow.findViewById(R.id.any_view).setOnTouchListener(new View.OnTouchListener() { @Override public boolean onTouch(View v, MotionEvent event) { int action = MotionEventCompat.getActionMasked(event); switch (action) { case MotionEvent.ACTION_UP: Log.d(TAG,"any_view clicked" ); break; } return true; } });
Manipulez le marqueur en cliquant séparément
@Override public boolean onMarkerClick(Marker marker) { Log.d(TAG,"on Marker Click called"); marker.showInfoWindow(); CameraPosition cameraPosition = new CameraPosition.Builder() .target(marker.getPosition()) // Sets the center of the map to Mountain View .zoom(10) .build(); mMap.animateCamera(CameraUpdateFactory.newCameraPosition(cameraPosition),1000,null); return true; }
la source
Juste une spéculation, je n'ai pas assez d'expérience pour l'essayer ...) -:
Étant donné que GoogleMap est un fragment, il devrait être possible d'attraper l'événement Marker onClick et d'afficher une vue fragmentée personnalisée . Un fragment de carte sera toujours visible en arrière-plan. Quelqu'un a-t-il essayé? Une raison pour laquelle cela ne pouvait pas fonctionner?
L'inconvénient est que le fragment de carte serait gelé sur l'arrière-plan, jusqu'à ce qu'un fragment d'information personnalisé lui retourne le contrôle.
la source
J'ai créé un exemple de projet de studio Android pour cette question.
captures d'écran de sortie: -
Téléchargez le code source complet du projet Cliquez ici
Remarque: vous devez ajouter votre clé API dans Androidmanifest.xml
la source
C'est vraiment simple.
googleMap.setInfoWindowAdapter(new InfoWindowAdapter() { // Use default InfoWindow frame @Override public View getInfoWindow(Marker marker) { return null; } // Defines the contents of the InfoWindow @Override public View getInfoContents(Marker marker) { // Getting view from the layout file info_window_layout View v = getLayoutInflater().inflate(R.layout.info_window_layout, null); // Getting reference to the TextView to set title TextView note = (TextView) v.findViewById(R.id.note); note.setText(marker.getTitle() ); // Returning the view containing InfoWindow contents return v; } });
Ajoutez simplement le code ci-dessus dans votre classe où vous utilisez GoogleMap. R.layout.info_window_layout est notre mise en page personnalisée qui montre la vue qui viendra à la place de l'infowindow. Je viens d'ajouter le textview ici. Vous pouvez ajouter une vue supplémentaire ici pour en faire un exemple d'accrochage. Mon info_window_layout était
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="wrap_content" android:layout_height="wrap_content" android:orientation="vertical" > <TextView android:id="@+id/note" android:layout_width="wrap_content" android:layout_height="wrap_content" /> </LinearLayout>
J'espère que cela aidera. Nous pouvons trouver un exemple fonctionnel d'infowindow personnalisé à l' adresse http://wptrafficanalyzer.in/blog/customizing-infowindow-contents-in-google-map-android-api-v2-using-infowindowadapter/#comment-39731
EDITED: Ce code montre comment nous pouvons ajouter une vue personnalisée sur infoWindow. Ce code n'a pas géré les clics sur les éléments de vue personnalisée. Il est donc proche de la réponse, mais pas exactement la réponse, c'est pourquoi cela n'est pas accepté comme réponse.
la source