Modifier la position du bouton "Ma position" de l'API Google Maps


84

J'utilise l'API Google Maps Android v2 et j'ai besoin d'un moyen de déterminer la position du bouton "Ma position".

J'obtiens le bouton "Ma position" comme ceci:

GooglePlayServicesUtil.isGooglePlayServicesAvailable(getApplicationContext());
final GoogleMap map = ((SupportMapFragment) getSupportFragmentManager()
        .findFragmentById(R.id.map)).getMap();

// This gets the button
map.setMyLocationEnabled(true);

2
AFAIK, vous ne le faites pas. Vous ajustez votre mise en page de sorte que l'annonce ne chevauche pas la carte.
CommonsWare

5
Avez-vous regardé la méthode setPadding () de GoogleMap? Voir: développeurs.google.com
maps

Réponses:


70

Utilisez simplement GoogleMap.setPadding (gauche, haut, droite, bas), qui vous permet d'indiquer les parties de la carte qui peuvent être masquées par d'autres vues. Le réglage du remplissage repositionne les commandes de carte standard et les mises à jour de la caméra utiliseront la zone remplie.

https://developers.google.com/maps/documentation/android/map#map_padding


6
C'est la meilleure réponse. findById (1) est une solution terrible
pablobaldez

La réponse la plus claire et la plus pratique. Aimer.
josefdlange

3
Fonctionne bien pour mettre le bouton de mylocation dans le coin inférieur droit, mais comme vous le dites, cela gâche les mises à jour de la caméra. Comment résoudre ça? À partir de maintenant, mon appareil photo voit toujours le bas de l'écran comme le centre. Ajoutez-vous la moitié de la hauteur de l'écran à la caméra lors du calcul des choses?
riper le

4
Je préfère le mapView.findViewWithTag ("GoogleMapMyLocationButton"); solution ci-dessous.
ayvazj

3
Notez que cela setPaddinga beaucoup d'autres effets secondaires qui peuvent être indésirables. Plus important encore, cela change la position de l'écran de la cible de la caméra.
zyamys

87

Vous pouvez obtenir le bouton "Ma position" et le déplacer, comme:

public class MapFragment extends SupportMapFragment {
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
    View mapView = super.onCreateView(inflater, container, savedInstanceState);   

    // Get the button view 
    View locationButton = ((View) mapView.findViewById(1).getParent()).findViewById(2);

    // and next place it, for exemple, on bottom right (as Google Maps app)
    RelativeLayout.LayoutParams rlp = (RelativeLayout.LayoutParams) locationButton.getLayoutParams();
    // position on right bottom
    rlp.addRule(RelativeLayout.ALIGN_PARENT_TOP, 0);
    rlp.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM, RelativeLayout.TRUE);
    rlp.setMargins(0, 0, 30, 30);
    }
}

4
Salut @fabLouis, Tout d'abord, je voulais vous remercier. Votre code a déplacé le LocationButton. Je suis juste curieux de savoir comment vous avez déterminé l'identifiant de ce bouton? Pouvez-vous expliquer plus à ce sujet mapView.findViewById(1).getParent()).findViewById(2);. Merci encore, SH
Swan

4
via le débogueur Android Studio
fabLouis

1
si vous faites cela, Android Studio dira "ressource attendue de type id"
dans le

11
@inmyth Même j'ai eu la même erreur, mais j'ai analysé 1 et 2 en utilisant la classe Integer. findViewById (Integer.parseInt ("1")). Si vous aviez trouvé une meilleure solution, faites-le moi savoir.
Harsha

2
hmm comment RelativeLayout.ALIGN_PARENT_TOPet RelativeLayout.ALIGN_PARENT_BOTTOMégal en bas à droite?
user2968401

15

Ce n'est peut-être pas la meilleure solution, mais vous pouvez placer votre propre bouton sur la carte et le gérer vous-même. Il faudrait ce qui suit: -

1) Mettez la carte dans un frameLayout et ajoutez votre bouton en haut. Par exemple

<FrameLayout
    android:id="@+id/mapFrame"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >



    <fragment
        xmlns:map="http://schemas.android.com/apk/res-auto"
        android:id="@+id/mapFragment"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        class="com.google.android.gms.maps.MapFragment"
        map:mapType="normal"
        map:uiCompass="true" />

    <ImageButton
        android:id="@+id/myMapLocationButton"
        android:layout_width="36dp"
        android:layout_height="36dp"
        android:layout_gravity="bottom|right"
        android:background="@drawable/myMapLocationDrawable"
        android:contentDescription="My Location" />

</FrameLayout>

2) Modifiez les paramètres de l'interface utilisateur des cartes afin que le bouton n'apparaisse pas lorsque vous appelez setMyLocationEnabled (true). Vous pouvez le faire via map.getUiSettings (). setMyLocationButtonEnabled (false);

3) Gérez le clic de votre nouveau bouton pour émuler ce que fait le bouton fourni. Par exemple, appelez mMap.setMyLocationEnabled (...); et déplacez la carte vers l'emplacement actuel.

J'espère que cela aide, ou j'espère que quelqu'un vous proposera une solution plus simple ;-)


BTW pour ce que ça vaut, je suis d'accord avec CommonsWare, ne pas couvrir la carte avec une publicité serait mieux!
Ryan

14

Cela a déjà été expliqué ci-dessus, juste un petit ajout à la réponse de fabLouis. Vous pouvez également obtenir votre vue cartographique à partir de SupportMapFragment.

        /**
         * Move the button
         */
        SupportMapFragment mapFragment = (SupportMapFragment) getSupportFragmentManager().
                findFragmentById(R.id.map);
        View mapView = mapFragment.getView();
        if (mapView != null &&
                mapView.findViewById(1) != null) {
            // Get the button view
            View locationButton = ((View) mapView.findViewById(1).getParent()).findViewById(2);
            // and next place it, on bottom right (as Google Maps app)
            RelativeLayout.LayoutParams layoutParams = (RelativeLayout.LayoutParams)
                    locationButton.getLayoutParams();
            // position on right bottom
            layoutParams.addRule(RelativeLayout.ALIGN_PARENT_TOP, 0);
            layoutParams.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM, RelativeLayout.TRUE);
            layoutParams.setMargins(0, 0, 30, 30);
        }

3
Cette ligne - ((Afficher) mapView.findViewById (1) .getParent ()). FindViewById (2); me donnait une erreur - "Ressource attendue de type ID" sur 1 et 2 entiers alors je l'ai résolu comme ceci ((Afficher) mapView.findViewById (Integer.parseInt ("1")). getParent ()). findViewById (Integer .parseInt ("2"));
Zohab Ali

14

Je n'ai pas envie de voir ces ID de vue magiques que d'autres utilisent, je suggère d'utiliser des balises pour trouver MapViewles enfants.

Voici ma solution pour placer le bouton Ma position au-dessus des commandes de zoom .

// Get map views
View location_button =_mapView.findViewWithTag("GoogleMapMyLocationButton");
View zoom_in_button = _mapView.findViewWithTag("GoogleMapZoomInButton");
View zoom_layout = (View) zoom_in_button.getParent();

// adjust location button layout params above the zoom layout
RelativeLayout.LayoutParams location_layout = (RelativeLayout.LayoutParams) location_button.getLayoutParams();
location_layout.addRule(RelativeLayout.ALIGN_PARENT_TOP, 0);
location_layout.addRule(RelativeLayout.ABOVE, zoom_layout.getId());

3
Pour quiconque se demande comment faire de même pour la boussole, la balise l'est GoogleMapCompass.
zyamys

1
Hey Cord, je ne sais pas si vous vous souvenez comment faire cela, mais vous souvenez-vous où vous avez trouvé la liste des balises mapview? Je cherche à déplacer d'autres choses et je n'aime vraiment pas les autres modèles que les gens utilisent.
Randy

2
@Randy Parcourez les sous-vues de MapView (FrameLayout) et enregistrez les balises pour les obtenir. Voir ici (Écrit à Kotlin)
ElegyD

@ElegyD Merci !!
Randy

12

J'ai résolu ce problème dans mon fragment de carte en repositionnant mon bouton de localisation dans le coin inférieur droit de la vue en utilisant le code ci-dessous, voici mon Maps Activity.java: -

ajoutez ces lignes de code dans la méthode onCreate (),

 SupportMapFragment mapFragment = (SupportMapFragment) getSupportFragmentManager()
                .findFragmentById(R.id.map);
        mapView = mapFragment.getView();
        mapFragment.getMapAsync(this);

et voici le code onMapReady (): -

@Override
        public void onMapReady(GoogleMap googleMap) {
            mMap = googleMap;
            mMap.setMyLocationEnabled(true);

            // Add a marker in Sydney and move the camera
            LatLng sydney = new LatLng(-34, 151);
            mMap.addMarker(new MarkerOptions().position(sydney).title("Marker in Sydney"));
            mMap.moveCamera(CameraUpdateFactory.newLatLng(sydney));

            if (mapView != null &&
                    mapView.findViewById(Integer.parseInt("1")) != null) {
                // Get the button view
                View locationButton = ((View) mapView.findViewById(Integer.parseInt("1")).getParent()).findViewById(Integer.parseInt("2"));
                // and next place it, on bottom right (as Google Maps app)
                RelativeLayout.LayoutParams layoutParams = (RelativeLayout.LayoutParams)
                        locationButton.getLayoutParams();
                // position on right bottom
                layoutParams.addRule(RelativeLayout.ALIGN_PARENT_TOP, 0);
                layoutParams.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM, RelativeLayout.TRUE);
                layoutParams.setMargins(0, 0, 30, 30);
            }

        }

J'espère que cela résoudra votre problème. Merci.


Merci a travaillé pour moi. J'essayais avec seulement ALIGN_PARENT_BOTTOM mais cela n'a pas fonctionné pour moi. comment ça marche?
Sharath Weaver

vous devez lancer (afficher) comme mapView = (Afficher) mapFragment.getView ();
Md Shihab Uddin

9

Tout d'abord, obtenez Google Map View:

 View mapView = ((MapFragment) getFragmentManager().findFragmentById(R.id.map)).getView();

Recherchez ensuite le bouton MyLocation (id du débogueur Android Studio):

 View btnMyLocation = ((View) mapView.findViewById(1).getParent()).findViewById(2);

Enfin, définissez simplement de nouveaux paramètres RelativeLayout pour le bouton MyLocation (aligner le parent à droite + centre verticalement dans ce cas):

RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(80,80); // size of button in dp
    params.addRule(RelativeLayout.ALIGN_PARENT_RIGHT, RelativeLayout.TRUE);
    params.addRule(RelativeLayout.CENTER_VERTICAL, RelativeLayout.TRUE);
    params.setMargins(0, 0, 20, 0);
    btnMyLocation.setLayoutParams(params);

Boom! Vous pouvez maintenant le déplacer comme vous le souhaitez;)


3
Cette ligne - ((Afficher) mapView.findViewById (1) .getParent ()). FindViewById (2); me donne une erreur - "Ressource attendue de type ID" sur 1 et 2 entiers.
zookastos

3
Essayez ceci - Afficher btnMyLocation = ((Afficher) mapView.findViewById (Integer.parseInt ("1")). GetParent ()). FindViewById (Integer.parseInt ("2"));
Silambarasan Poonguti

@Nalin Il y a une option si vous Alt-Enter sur l'erreur pour désactiver la vérification (par exemple pour la méthode).
Richard Le Mesurier

8

Voir la méthode ci-dessous. Il vit dans une classe qui étend SupportMapFragment. Il obtient la vue du conteneur pour le bouton et l'affiche en bas, centré horizontalement.

/**
     * Move my position button at the bottom of map
     */
    private void resetMyPositionButton()
    {
        //deep paths for map controls
        ViewGroup v1 = (ViewGroup)this.getView();
        ViewGroup v2 = (ViewGroup)v1.getChildAt(0);
        ViewGroup v3 = (ViewGroup)v2.getChildAt(0);
        ViewGroup v4 = (ViewGroup)v3.getChildAt(1);

        //my position button
        View position =  (View)v4.getChildAt(0);

        int positionWidth = position.getLayoutParams().width;
        int positionHeight = position.getLayoutParams().height;

        //lay out position button
        RelativeLayout.LayoutParams positionParams = new RelativeLayout.LayoutParams(positionWidth,positionHeight);
        int margin = positionWidth/5;
        positionParams.setMargins(0, 0, 0, margin);
        positionParams.addRule(RelativeLayout.CENTER_HORIZONTAL, RelativeLayout.TRUE);
        positionParams.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM, RelativeLayout.TRUE);
        position.setLayoutParams(positionParams);
    }

cela me donne java.lang.ClassCastException: maps.af.q ne peut pas être casté sur android.view.ViewGroup
Nayanesh Gupte

8

Si vous souhaitez simplement activer l'indication de position (le point bleu) mais que vous n'avez pas besoin du bouton Ma position par défaut:

mGoogleMap.setMyLocationEnabled(true);
mGoogleMap.getUiSettings().setMyLocationButtonEnabled(false);

De cette façon, vous pouvez également dessiner votre propre bouton où vous le souhaitez sans trucs étranges comme celui-ci mapView.findViewById(1).getParent()).


Merci beaucoup
Nacho Zullo

2

J'ai eu le même problème. J'ai fini par utiliser le visualiseur de hiérarchie pour identifier la vue utilisée pour afficher le bouton et je l'ai manipulé. Très piraté, je sais, mais je n'ai pas pu trouver une autre manière.


1
Pourriez-vous partager votre solution s'il vous plaît.
clauziere

2

Ce fut un peu difficile pour que cela fonctionne. Mais je l'ai fait, et dans le processus, j'ai également commencé à déplacer les boutons de zoom. Voici mon code complet:

package com.squirrel.hkairpollution;

import android.os.Bundle;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.RelativeLayout;

import com.google.android.gms.maps.CameraUpdateFactory;
import com.google.android.gms.maps.SupportMapFragment;
import com.google.android.gms.maps.UiSettings;
import com.google.android.gms.maps.model.LatLng;

public class MySupportMapFragment extends SupportMapFragment {

private static final String TAG = HKAirPollution.TAG;

public MySupportMapFragment() {
    return;
}

@Override
public View onCreateView(LayoutInflater arg0, ViewGroup arg1, Bundle arg2) {
    Log.v(TAG, "In overridden onCreateView.");
    View v = super.onCreateView(arg0, arg1, arg2);
    Log.v(TAG, "Initialising map.");
    initMap();
    return v;
}

@Override
 public void onViewCreated (View view, Bundle savedInstanceState) {
    super.onViewCreated(view, savedInstanceState);
    resetButtons();
}

private void initMap(){
    UiSettings settings = getMap().getUiSettings();
    settings.setAllGesturesEnabled(true);
    settings.setMyLocationButtonEnabled(true);
    LatLng latLong = new LatLng(22.320542, 114.185715);
    getMap().moveCamera(CameraUpdateFactory.newLatLngZoom(latLong,11));
}


/**
 * Move my position button at the bottom of map
 */
private void resetButtons()
{
    // Get a reference to the zoom buttons and the position button.
    ViewGroup v1 = (ViewGroup)this.getView();
    ViewGroup v2 = (ViewGroup)v1.getChildAt(0);
    ViewGroup v3 = (ViewGroup)v2.getChildAt(0);
    ViewGroup v4 = (ViewGroup)v3.getChildAt(1);

    // The My Position button
    View position =  (View)v4.getChildAt(0);
    int positionWidth = position.getLayoutParams().width;
    int positionHeight = position.getLayoutParams().height;

    // Lay out the My Position button.
    RelativeLayout.LayoutParams positionParams = new RelativeLayout.LayoutParams(positionWidth,positionHeight);
    int margin = positionWidth/5;
    positionParams.setMargins(0, 0, 0, margin);
    positionParams.addRule(RelativeLayout.CENTER_HORIZONTAL, RelativeLayout.TRUE);
    positionParams.addRule(RelativeLayout.ALIGN_PARENT_TOP, RelativeLayout.TRUE);
    position.setLayoutParams(positionParams);

    // The Zoom buttons
    View zoom = (View)v4.getChildAt(2);
    int zoomWidth = zoom.getLayoutParams().width;
    int zoomHeight = zoom.getLayoutParams().height;

    // Lay out the Zoom buttons.
    RelativeLayout.LayoutParams zoomParams = new RelativeLayout.LayoutParams(zoomWidth, zoomHeight);
    zoomParams.setMargins(0, 0, 0, margin);
    zoomParams.addRule(RelativeLayout.ALIGN_PARENT_RIGHT, RelativeLayout.TRUE);
    zoomParams.addRule(RelativeLayout.ALIGN_PARENT_TOP, RelativeLayout.TRUE);
    zoom.setLayoutParams(zoomParams);
} 
}

2

Une façon de résoudre ce problème. Supprimer le bouton par défaut et créer le vôtre. Dans l'instruction OnCreate, ajoutez le suivant:

GoogleMap mMap = ((MapView) inflatedView.findViewById(R.id.mapview)).getMap();
LocationManager locationManager =    
(LocationManager)getActivity().getSystemService(Context.LOCATION_SERVICE);
Criteria criteria = new Criteria();
String provider = locationManager.getBestProvider(criteria, false);
Location location = locationManager.getLastKnownLocation(provider);
locationManager.requestLocationUpdates(provider, 2000, 1,  this);

mMap.setMyLocationEnabled(true);
mMap.getUiSettings().setMyLocationButtonEnabled(false); // delete default button

Imagebutton imgbtn = (ImageButton) view.findViewById(R.id.imgbutton); //your button
imgbtn.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            mMap.animateCamera(CameraUpdateFactory.newLatLngZoom(new    
LatLng(location.getLatitude(),     
location.getLongitude()), 15));
        }
    });

2

essayez ce code

private void resetMyPositionButton()
{
    Fragment fragment = ( (SupportMapFragment) getSupportFragmentManager().findFragmentById( R.id.map ) );
    ViewGroup v1 = (ViewGroup) fragment.getView();
    ViewGroup v2 = (ViewGroup)v1.getChildAt(0);
    ViewGroup v3 = (ViewGroup)v2.getChildAt(2);
    View position =  (View)v3.getChildAt(0);
    int positionWidth = position.getLayoutParams().width;
    int positionHeight = position.getLayoutParams().height;

    //lay out position button
    RelativeLayout.LayoutParams positionParams = new RelativeLayout.LayoutParams(positionWidth,positionHeight);
    int margin = positionWidth/5;
    positionParams.setMargins(margin, 0, 0, margin);
    positionParams.addRule(RelativeLayout.CENTER_VERTICAL, RelativeLayout.TRUE);
    positionParams.addRule(RelativeLayout.ALIGN_PARENT_LEFT, RelativeLayout.TRUE);
    position.setLayoutParams(positionParams);
}

2

Ce bouton a été déplacé sur le côté gauche de la carteAvant, vous pouviez supprimer l'ancienne règle du bouton:

@Override
public void onMapReady(final GoogleMap googleMap) {
    this.map = googleMap;
    // Show location button
    View locationButton = ((View) mapView.findViewById(Integer.parseInt("1")).getParent()).findViewById(Integer.parseInt("2"));
    RelativeLayout.LayoutParams rlp = (RelativeLayout.LayoutParams) locationButton.getLayoutParams();
    // position on right bottom
    Log.l(Arrays.toString(rlp.getRules()), L.getLogInfo());
    int[] ruleList = rlp.getRules();
    for (int i = 0; i < ruleList.length; i ++) {
        rlp.removeRule(i);
    }
    Log.l(Arrays.toString(rlp.getRules()), L.getLogInfo());
    //Do what you want to move this location button:
    rlp.addRule(RelativeLayout.CENTER_IN_PARENT, RelativeLayout.TRUE);
    rlp.addRule(RelativeLayout.ALIGN_PARENT_LEFT, RelativeLayout.TRUE);
}

0

Vous pouvez utiliser l'approche suivante:

    View myLocationParent = ((View) getView().findViewById(1).getParent());
    View myLocationParentParent = ((View) myLocationParent.getParent());

    // my position button

    int positionWidth = myLocationParent.getLayoutParams().width;
    int positionHeight = myLocationParent.getLayoutParams().height;

    // lay out position button
    FrameLayout.LayoutParams positionParams = new FrameLayout.LayoutParams(
            positionWidth, positionHeight);
    positionParams.setMargins(0, 100, 0, 0);

    myLocationParent.setLayoutParams(positionParams);

comment saviez-vous que ((View) getView (). findViewById (1) .getParent ()); obtiendrait la vue de l'emplacement?
reidisaki le

Il y a beaucoup de bonnes choses dans le débogueur Android Studio;)
Roman

0

J'ai ajouté une ligne à mon fragment android: layout_marginTop = "? Attr / actionBarSize" Cela m'a aidé


0

utilisez celui-ci pour l'emplacement en bas à droite

map.setMyLocationEnabled(true); 
map.setPadding(0,1600,0,0);
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.