web-dev-qa-db-fra.com

android Maps API v2 avec des marqueurs personnalisés

Je veux faire des cartes avec des marqueurs personnalisés. Dans API v2, je peux définir une icône, un titre, etc. pour les marqueurs. Mais je veux afficher le titre avec le marqueur au début. Maintenant, le titre ne s'affiche que lorsque je tape le marqueur. Dans la v1, il y avait des superpositions, mais dans la v2, je n'ai rien trouvé de similaire.

Edited: Peut-être que je n'étais pas assez clair. Quelque chose comme Marker.showInfoWindow() dans l'API ne fonctionne que pour un marqueur. Je ne peux pas afficher les fenêtres d'informations pour tous mes marqueurs en même temps. Quoi qu'il en soit, je dois afficher les titres de tous mes marqueurs, sans attendre pendant que l'utilisateur tape dessus.

65
jumper0k

Je suis également tombé sur ce problème. L'API V2 est un pas en avant, deux pas en arrière. Google, veuillez ajouter une méthode de 'dessin' pouvant être remplacée sur les classes Marker ou GoogleMap afin que nous puissions personnaliser le dessin nous-mêmes.

Une solution possible consiste à générer le bitmap à la volée et à l’attacher au marqueur. c'est-à-dire créer un canevas, insérer le bitmap du marqueur, dessiner le texte en regard du marqueur. Cela implique des calculs pénibles (la taille de la toile appropriée avec le bitmap de marqueur et le texte côte à côte). Malheureusement, il n'y a pas de méthode setIcon dans Marker, donc chaque fois que le texte change, un nouveau marqueur doit être créé. Cela peut aller si vous avez juste un marqueur sur la carte, mais avec des dizaines de marqueurs, cela risque de ne pas être réalisable. Il peut également y avoir un problème de mémoire lors de la création dynamique de ces bitmaps. Un exemple de code (avec juste le texte):

Bitmap.Config conf = Bitmap.Config.ARGB_8888; 
Bitmap bmp = Bitmap.createBitmap(200, 50, conf); 
Canvas canvas = new Canvas(bmp);

canvas.drawText("TEXT", 0, 50, Paint); // Paint defines the text color, stroke width, size
mMap.addMarker(new MarkerOptions()
                                .position(clickedPosition)
                                //.icon(BitmapDescriptorFactory.fromResource(R.drawable.marker2))
                                .icon(BitmapDescriptorFactory.fromBitmap(bmp))
                                .anchor(0.5f, 1)
                                    );

Espérons que Google ajoutera les méthodes appropriées afin que nous puissions le faire facilement. Bon sang, j'aime beaucoup la nouvelle fonctionnalité de rotation de la carte dans l'API V2.

83
azgolfer

Finalement l'a fait. Donc, ce que vous faites est une image de fond (dans mon cas, je viens d'utiliser un rectangle bleu). Créez un marqueur comme ceci:

Marker myLocMarker = map.addMarker(new MarkerOptions()
            .position(myLocation)
            .icon(BitmapDescriptorFactory.fromBitmap(writeTextOnDrawable(R.drawable.bluebox, "your text goes here"))));

Notez la méthode writeTextOnDrawable ():

private Bitmap writeTextOnDrawable(int drawableId, String text) {

    Bitmap bm = BitmapFactory.decodeResource(getResources(), drawableId)
            .copy(Bitmap.Config.ARGB_8888, true);

    Typeface tf = Typeface.create("Helvetica", Typeface.BOLD);

    Paint paint = new Paint();
    Paint.setStyle(Style.FILL);
    Paint.setColor(Color.WHITE);
    Paint.setTypeface(tf);
    Paint.setTextAlign(Align.CENTER);
    Paint.setTextSize(convertToPixels(context, 11));

    Rect textRect = new Rect();
    Paint.getTextBounds(text, 0, text.length(), textRect);

    Canvas canvas = new Canvas(bm);

    //If the text is bigger than the canvas , reduce the font size
    if(textRect.width() >= (canvas.getWidth() - 4))     //the padding on either sides is considered as 4, so as to appropriately fit in the text
        Paint.setTextSize(convertToPixels(context, 7));        //Scaling needs to be used for different dpi's

    //Calculate the positions
    int xPos = (canvas.getWidth() / 2) - 2;     //-2 is for regulating the x position offset

    //"- ((Paint.descent() + Paint.ascent()) / 2)" is the distance from the baseline to the center.
    int yPos = (int) ((canvas.getHeight() / 2) - ((Paint.descent() + Paint.ascent()) / 2)) ;  

    canvas.drawText(text, xPos, yPos, Paint);

    return  bm;
}



public static int convertToPixels(Context context, int nDP)
{
    final float conversionScale = context.getResources().getDisplayMetrics().density;

    return (int) ((nDP * conversionScale) + 0.5f) ;

}

Merci à Arun George: Ajoutez du texte à l'image dans Android par programmation

48
JY2k

On dirait que votre question a finalement reçu une réponse lors d'une session Google I/O.

Regardez http://googlemaps.github.io/Android-maps-utils/

Il a:

Regroupement de marqueurs - gère l'affichage d'un grand nombre de points

Cartes thermiques - Affiche un grand nombre de points sous forme de carte thermique

IconGenerator - affiche du texte sur vos marqueurs (voir capture d'écran)

Markers made using the library

De manière très importante, il peut être modifié sur any thread , de sorte que manipuler de nombreux marqueurs est un jeu d'enfant.

15
vedant

Je ne suis pas sûr de ce que vous essayez d'atteindre: afficher la fenêtre d'information sans que l'utilisateur ne soit obligé de taper sur le marqueur, ou utiliser une vue complètement différente pour la fenêtre d'information (ou peut-être les deux).

Pour afficher la fenêtre d’information sans nécessiter un utilisateur, appuyez sur:

Je n'ai pas testé cela moi-même, mais j'imagine que Marker.showInfoWindow () ferait l'affaire (en supposant que la visibilité du marqueur est déjà true.

Pour fournir une vue personnalisée à InfoWindow

Il y a deux options ici et vous devriez vous référer à la documentation sur GoogleMap.InfoWindowAdapter :

interface statique publique GoogleMap.InfoWindowAdapter

Fournit des vues pour un rendu personnalisé des fenêtres d’information.

Les méthodes de ce fournisseur sont appelées lorsqu'il est temps d'afficher une fenêtre d'informations pour un marqueur, quelle qu'en soit la cause (un geste de l'utilisateur ou un appel programmatique à showInfoWindow (). Puisqu'une seule fenêtre d'informations est affichée à la fois, ce fournisseur peut choisir de réutiliser des vues ou de créer de nouvelles vues à chaque appel de méthode.

Lors de la construction d'une fenêtre d'information, les méthodes de cette classe sont appelées dans un ordre défini. Pour remplacer la fenêtre d'information par défaut, remplacez getInfoWindow (Marker) par votre rendu personnalisé. Pour remplacer uniquement le contenu de la fenêtre d'information, dans le cadre par défaut de la fenêtre d'information (la bulle de légende), laissez l'implémentation par défaut de getInfoWindow (Marker) et remplacez plutôt getInfoContents (Marker).

Fondamentalement, si vous remplacez getInfoWindow() ou getInfoContents(), cela dépend si vous souhaitez ou non personnaliser ce que vous voyez dans la bulle de légende ou si vous souhaitez personnaliser la totalité de la fenêtre d'information. , y compris une alternative à la bulle de légende.

Une mise en garde: je pense que lorsque vous substituez ces méthodes, il effectue un rendu simple de ce à quoi ressemble la vue au moment où getInfoWindow() ou getInfoContents() est appelée. Je suis moi-même intéressé à essayer de reproduire le look de l'application Google Maps native Android app qui comporte une petite icône "directions" à côté du nom de l'endroit. Je crois qu'un des problèmes (voir here: https://stackoverflow.com/a/13713536/129475 ) est que si vous avez quelque chose comme un bouton dans votre vue, il se peut qu'il ne se comporte pas comme un bouton à cause du rendu statique.

9
Bryce Thomas

Personnaliser l'image du marqueur

Vous pouvez remplacer l'image de marqueur par défaut par une image de marqueur personnalisée, souvent appelée icône. Les icônes personnalisées sont toujours définies en tant que BitmapDescriptor et définies à l'aide de l'une des quatre méthodes de la classe BitmapDescriptorFactory.

fromAsset (String assetName) Crée un marqueur personnalisé à l'aide d'une image du répertoire des actifs.

fromBitmap (image bitmap) Crée un marqueur personnalisé à partir d'une image bitmap.

fromFile (String path) Crée une icône personnalisée à partir d'un fichier situé dans le chemin spécifié.

fromResource (int resourceId) Crée un marqueur personnalisé à l'aide d'une ressource existante. L'extrait ci-dessous crée un marqueur avec une icône personnalisée.

 private static final LatLng MELBOURNE = new LatLng(-37.813, 144.962);
 private Marker melbourne = mMap.addMarker(new MarkerOptions()
                        .position(MELBOURNE)
                        .title("Melbourne")
                        .snippet("Population: 4,137,400")
                        .icon(BitmapDescriptorFactory.fromResource(R.drawable.arrow)));
4
sujith s

Ce code simple fonctionne pour afficher le titre sans nécessiter un événement de clic:

googleMap.addMarker(new MarkerOptions()
        .position(latLng)
        .title(String title))
        .showInfoWindow();
1
Cohen

Google a mis au point la classe IconGenerator qui facilite l’ajout d’icône personnalisée.

IconGenerator iconGenerator = new IconGenerator(mContext);
Bitmap bitmap = iconGenerator.makeIcon("Text Of Icon");
mMap.addMarker(new MarkerOptions()
                      .position(latlng)
                      .title("Location")
                      .icon(BitmapDescriptorFactory.fromBitmap(bitmap)));
0
Darragh O'Flaherty

Pourquoi ne gardez-vous pas un tableau des marqueurs alors, quand il s'agit de les afficher, parcourez-les en appelant showInfoWindow(). Ce n’est peut-être pas la solution la plus élégante, mais c’est ce que vous dites, je pense.

0
StuStirling