Modifica la posizione del pulsante "La mia posizione" dell'API di Google Maps


84

Sto utilizzando l'API Android di Google Maps v2 e ho bisogno di un modo per controllare la posizione del pulsante "La mia posizione".

Ottengo il pulsante "La mia posizione" in questo modo:

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

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

2
AFAIK, non lo fai. Regoli il layout in modo che l'annuncio non si sovrapponga alla mappa.
CommonsWare

5
Hai esaminato il metodo setPadding () di GoogleMap? Vedi: developers.google.com/maps/documentation/android/…
IgorGanapolsky

Risposte:


70

Basta usare GoogleMap.setPadding (sinistra, in alto, a destra, in basso), che ti consente di indicare parti della mappa che potrebbero essere oscurate da altre visualizzazioni. L'impostazione del riempimento riposiziona i controlli della mappa standard e gli aggiornamenti della telecamera utilizzeranno la regione imbottita.

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


6
Questa è la migliore risposta. findById (1) è una soluzione terribile
pablobaldez

La risposta più chiara e migliore in assoluto. Lo adoro.
josefdlange

3
Funziona bene per mettere il pulsante mylocation nell'angolo in basso a destra, ma come dici tu rovina gli aggiornamenti della fotocamera. Come risolverlo? A partire da ora la mia fotocamera vede sempre la parte inferiore dello schermo come il centro. Aggiungete metà dell'altezza dello schermo alla fotocamera durante il calcolo delle cose?
più maturo

4
Preferisco mapView.findViewWithTag ("GoogleMapMyLocationButton"); soluzione di seguito.
ayvazj

3
Nota che setPaddingha molti altri effetti collaterali che potrebbero essere indesiderati. Ancora più importante, cambia la posizione dello schermo del target della telecamera.
zyamys

87

Puoi ottenere il pulsante "La mia posizione" e spostarlo, ad esempio:

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
Ciao @fabLouis, prima di tutto volevo ringraziarti. Il tuo codice ha spostato il LocationButton. Sono solo curioso di sapere come hai capito l'ID di quel pulsante? Puoi spiegare di più su questo mapView.findViewById(1).getParent()).findViewById(2);. Grazie ancora, SH
Swan

4
tramite il debugger di Android Studio
fabLouis

1
se
esegui

11
@inmyth Anche io ho ricevuto lo stesso errore, ma ho analizzato 1 e 2 usando la classe Integer. findViewById (Integer.parseInt ("1")). Se hai trovato una soluzione migliore fammelo sapere.
Harsha

2
hmm come funziona RelativeLayout.ALIGN_PARENT_TOPe RelativeLayout.ALIGN_PARENT_BOTTOMuguale in basso a destra?
user2968401

15

Questa potrebbe non essere la soluzione migliore, ma potresti posizionare il tuo pulsante sulla mappa e gestirlo da solo. Ci vorrebbe quanto segue: -

1) Metti la mappa in un frameLayout e aggiungi il tuo pulsante in alto. Per esempio

<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) Modifica le impostazioni dell'interfaccia utente delle mappe in modo che il pulsante non venga visualizzato quando chiami setMyLocationEnabled (true). Puoi farlo tramite map.getUiSettings (). setMyLocationButtonEnabled (false);

3) Gestisci il clic del tuo nuovo pulsante per emulare ciò che fa il pulsante fornito. Ad esempio, chiama mMap.setMyLocationEnabled (...); e sposta la mappa sulla posizione corrente.

Spero che questo aiuti, o spero che qualcuno arrivi da tempo con una soluzione più semplice per te ;-)


A proposito per quello che vale, sono d'accordo con CommonsWare, non coprire la mappa con una pubblicità sarebbe meglio!
Ryan

14

È già stato spiegato sopra, solo una piccola aggiunta alla risposta di fabLouis. È inoltre possibile ottenere la visualizzazione della mappa da 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
Questa riga - ((View) mapView.findViewById (1) .getParent ()). FindViewById (2); mi dava un errore - "Risorsa prevista di tipo ID" su 1 e 2 interi, quindi l'ho risolto in questo modo ((View) mapView.findViewById (Integer.parseInt ("1")). getParent ()). findViewById (Integer .parseInt ("2"));
Zohab Ali

14

Non mi piace vedere questi ID di visualizzazione magica che altri usano, suggerisco di usare i tag per trovare MapViewi bambini.

Ecco la mia soluzione per posizionare il pulsante La mia posizione sopra i controlli dello 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
Per chiunque si chieda come fare lo stesso per la bussola, il tag è GoogleMapCompass.
zyamys

1
Ehi Cord, non so se ricordi come farlo, ma ricordi dove hai trovato l'elenco dei tag mapview? Sto cercando di spostare alcune altre cose e non mi piacciono gli altri modelli che le persone stanno usando.
Randy

2
@Randy Scorri le sottoview di MapView (FrameLayout) e registra i tag per ottenerli. Vedi qui (scritto in Kotlin)
ElegyD

@ElegyD Grazie !!
Randy

12

Ho risolto questo problema nel mio frammento di mappa riposizionando il pulsante della mia posizione nell'angolo inferiore destro della vista utilizzando il codice qui sotto, ecco la mia attività sulle mappe.java: -

aggiungi queste righe di codice nel metodo onCreate (),

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

ed ecco il codice 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);
            }

        }

Spero che questo risolva il tuo problema. Grazie.


Grazie ha funzionato per me. Stavo provando solo con ALIGN_PARENT_BOTTOM ma non ha funzionato per me. come funziona?
Sharath Weaver,

devi eseguire il cast (view) come mapView = (View) mapFragment.getView ();
Md Shihab Uddin

9

Per prima cosa, ottieni Google Map View:

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

Quindi trova il pulsante MyLocation (ID dal debugger di Android Studio):

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

Infine, imposta i nuovi parametri RelativeLayout per il pulsante MyLocation (allinea il genitore a destra + centro verticalmente in questo caso):

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! Ora puoi spostarlo come vuoi;)


3
Questa riga - ((View) mapView.findViewById (1) .getParent ()). FindViewById (2); mi dà un errore - "Risorsa prevista di tipo ID" su 1 e 2 numeri interi.
zookastos

3
Prova questo - Visualizza btnMyLocation = ((Visualizza) mapView.findViewById (Integer.parseInt ("1")). GetParent ()). FindViewById (Integer.parseInt ("2"));
Silambarasan Poonguti

@Nalin C'è un'opzione se si preme Alt-Invio sull'errore per disabilitare il controllo (ad esempio per il metodo).
Richard Le Mesurier

8

Vedere il metodo di seguito. Vive all'interno di una classe che estende SupportMapFragment. Ottiene la visualizzazione contenitore per il pulsante e la visualizza in basso, centrata orizzontalmente.

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

mi dà java.lang.ClassCastException: maps.af.q non può essere trasmesso ad android.view.ViewGroup
Nayanesh Gupte

8

Se desideri solo abilitare l'indicazione della posizione (il punto blu) ma non è necessario il pulsante predefinito La mia posizione:

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

In questo modo puoi anche disegnare il tuo pulsante dove vuoi senza cose strane come questa mapView.findViewById(1).getParent()).


Grazie mille
Nacho Zullo

2

Ho avuto lo stesso problema. Ho finito per utilizzare il visualizzatore della gerarchia per identificare la vista utilizzata per visualizzare il pulsante e manipolarlo. Molto hacky, lo so, ma non riuscivo a capire un modo diverso.


1
Potresti condividere la tua soluzione per favore.
clauziere

2

È stato un po 'faticoso farlo funzionare. Ma l'ho fatto e nel processo ho anche iniziato a spostare i pulsanti di zoom. Qui il mio codice completo:

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

Un modo per affrontare questo problema. Elimina il pulsante predefinito e creane uno personalizzato. Nell'istruzione OnCreate aggiungere il successivo:

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

prova questo codice

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

Questo pulsante è stato spostato sul lato sinistro della mappaPrima, potresti rimuovere la vecchia regola del pulsante:

@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

È possibile utilizzare il seguente approccio:

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

come sapevi che ((View) getView (). findViewById (1) .getParent ()); otterrebbe la visualizzazione della posizione?
reidisaki

Ci sono molte cose fantastiche nel debugger di Android Studio;)
Roman

0

Ho aggiunto una riga al mio frammento android: layout_marginTop = "? Attr / actionBarSize" Mi ha aiutato


0

usa questo per la posizione in basso a destra

map.setMyLocationEnabled(true); 
map.setPadding(0,1600,0,0);
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.