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);
Jakob
la source
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

Ascot Harris
la source
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);
    }
}
fabLouis
la source
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 ;-)

Ryan
la source
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);
        }
Sahil Jain
la source
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());
Cordon Rehn
la source
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.

Priya Jagtap
la source
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;)

romain
la source
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);
    }
oviroa
la source
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()).

fraggjkee
la source
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.

oviroa
la source
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);
} 
}
Wouter
la source
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));
        }
    });
Daryn
la source
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);
}
Métro Polinet
la source
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);
}
nobjta_9x_tq
la source
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);
Nayanesh Gupte
la source
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é

Oleg
la source
0

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

map.setMyLocationEnabled(true); 
map.setPadding(0,1600,0,0);
Muazziss ​​Najmi
la source