2013-01-13 7 views
10

Ho aggiunto un frammento di mappa (API v2) alla mia app con la mappa che copre l'intero schermo e una barra di azione semitrasparente in cima. L'attività utilizza un tema con android: windowActionBarOverlay impostato su true.Pulsante MyLocation nascosto dietro la barra di azione trasparente, come riposizionarlo?

Ho anche abilitato "MyLocationButton" sulla mappa, ma poiché la mappa copre l'intera altezza dello schermo, il pulsante è coperto dalla barra delle azioni.

enter image description here

Come posso fare il frammento di carta disegnare il pulsante sottostante barra delle operazioni o nella parte inferiore dello schermo invece?

+0

http://stackoverflow.com/a/20750956/1066839 – John

risposta

0

Assicurarsi di utilizzare ?android:attr/actionBarSize (o ?attr/actionBarSize se si utilizza ActionBarSherlock) per compensare correttamente il contenuto del frammento.

A seconda dell'effetto che si sta tentando di eseguire, applicare questo valore come margine o riempimento. Immagino che a causa della ActionBar semitrasparente, dovrai provare a riempire, in modo da far apparire la mappa dietro di essa (e mantenere l'effetto trasparente). Non sono sicuro al 100% se il padding sposterà effettivamente il pulsante "Locate me" ... In caso contrario, probabilmente l'applicazione di un margine è l'unica altra opzione.

Vedere here per un esempio e ulteriori dettagli su questo attributo.

+0

Questo riposiziona correttamente il pulsante La mia posizione, ma la sovrapposizione della barra di azione trasparente viene persa per una barra di azione solida. L'attributo margin è applicabile al frammento parent e al frammento stesso, ma l'attributo padding funziona solo quando è impostato nel genitore. Ad ogni modo, questo produce una barra di azione solida. – qubz

1

Questo è già stato archiviato come un miglioramento (si prega di stella, se non l'hai già) http://code.google.com/p/gmaps-api-issues/issues/detail?id=4670

Come soluzione temporanea ho aggiunto il mio tasto posizione seguito troverete l'ActionBar (mia mappa frammento è in una RelativeLayout quindi ho appena fatto alignParentRight e impostato il margine appropriato in alto).

Poi nel mio onClickHandler ho fatto questo:

public void onClickHandler(View target) { 
    switch (target.getId()) { 
     case R.id.my_fml_btn:   
     mMap.setMyLocationEnabled(true); 
     View fmlBtn = mMapWrapper.findViewById(2); //mMapWrapper is my RelativeLayout 
     if (fmlBtn != null) fmlBtn.setVisibility(View.INVISIBLE); 
     break; 
    } 
} 

ho usato hierarchyviewer Per trovare l'ID del pulsante che è stata aggiunta dal api mappe. Capita semplicemente di essere la seconda vista aggiunta alla mappa (e impostata su invisibile).

Ovviamente è possibile giocare con LayoutParams per sfalsare questo pulsante anziché nasconderlo, ma questo pulsante viene visualizzato solo dopo aver impostato MyLocationEnabled su true! (nel mio caso d'uso preferisco lasciare decidere all'utente prima di avviare il gps)

+0

Grazie per il link. ha recitato. – machtnix

+0

Ha funzionato per me! Grazie – Coderji

6

Invece di creare il proprio pulsante, basta spostare il pulsante di costruzione in base alla dimensione della barra di azione.
Questo codice funziona per me e il pulsante è proprio dove il tasto dovrebbe essere (come in google maps):

// Gets the my location button 
View myLocationButton = getSherlockActivity().findViewById(R.id.MainContainer).findViewById(2); 

// Checks if we found the my location button   
if (myLocationButton != null){ 
     int actionBarHeight = 0; 
     TypedValue tv = new TypedValue(); 

      // Checks if the os version has actionbar in it or not 
      if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB){ 
       if (getSherlockActivity().getTheme().resolveAttribute(android.R.attr.actionBarSize, tv, true)) 
       actionBarHeight = TypedValue.complexToDimensionPixelSize(tv.data,getResources().getDisplayMetrics()); 
      } 
      // Before the action bar was added to the api 
      else if(getSherlockActivity().getTheme().resolveAttribute(com.actionbarsherlock.R.attr.actionBarSize, tv, true)){ 
       actionBarHeight = TypedValue.complexToDimensionPixelSize(tv.data,getResources().getDisplayMetrics()); 
      } 

     // Sets the margin of the button 
     ViewGroup.MarginLayoutParams marginParams = new ViewGroup.MarginLayoutParams(myLocationButton.getLayoutParams()); 
     marginParams.setMargins(0, actionBarHeight + 20, 20, 0); 
     RelativeLayout.LayoutParams layoutParams = new RelativeLayout.LayoutParams(marginParams); 
     layoutParams.addRule(RelativeLayout.ALIGN_PARENT_RIGHT, RelativeLayout.TRUE); 
     myLocationButton.setLayoutParams(layoutParams); 
} 


Basta inserire questo codice nel onActivityCreated (se si vuole mettere nel onCreateOptionsMenu, non supporta la versione 3.0 prima - perché il ciclo di vita non è diversa
Un'altra cosa, il "R.id.MainContainer" è il contenitore del frammento mappa

sto usin.. g ActionBar Sherlock, ma funzionerà anche per la normale barra delle azioni con alcune modifiche ..

+0

Si prega di provare questo codice e se funzionerà per voi contrassegnarlo come risposta in modo che altre persone lo userà. Funziona per me .. –

+0

Mi sembra una cattiva pratica avere il magico numero 2 elencato nella chiamata findViewById nella seconda riga del codice di esempio. Non includi una spiegazione su dove hai trovato quel numero e se possiamo o meno contare su quel numero per non cambiarlo, specialmente se non è un ID che Google ha documentato. Se decidono di cambiare l'ID, allora sarai rotto. – Steven

+0

L'ID proviene dal gerarchyviewer .. E sono d'accordo, se Google lo cambierà devi anche cambiarlo. Ma tu controlli il tuo rilascio e se Google aggiorna i loro servizi di google-play, dovrai implementarlo prima di rilasciarlo. Nel peggiore dei casi, se lo cambieranno, controlla il nuovo ID nel gerarchyviewer .. E non dimenticare che questo è solo fino a quando non risolveranno questo problema: http://code.google.com/p/gmaps-api -issues/issues/detail? id = 4670 –

3

Sotto (in particolare in fixMapControlLocations) ho risolto questo problema con ActionBarSherlock.

I problemi che avevo erano su schermi stretti e la barra di azione divisa con offset errato a seconda della rotazione. Il controllo isNarrow attraverso lo sherlock mi consente di sapere se è stretto.

Un altro cambiamento chiave è che sto impostando il padding della vista genitore del genitore di myLocation. Questo preleva tutti i controlli all'interno, e in base al gerarchia di visualizzazione è come Google sta facendo. Il logo di attribuzione di Google si trova sul prossimo superiore dell'albero in un oggetto Superficie. Non sembra che sia facilmente spostabile, quindi probabilmente finirò per perdere l'effetto di trasparenza della barra delle azioni in basso per mantenere la conformità.

protected void onCreate(Bundle savedInstanceState) { 
    getWindow().requestFeature(Window.FEATURE_ACTION_BAR_OVERLAY); 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.map); 
    setUpMapIfNeeded(); 

    getSupportActionBar().setBackgroundDrawable(d); 
    getSupportActionBar().setSplitBackgroundDrawable(d); 
} 

private void setUpMapIfNeeded() { 
    // Do a null check to confirm that we have not already instantiated the 
    // map. 
    if (map == null) { 
     // Try to obtain the map from the SupportMapFragment. 
     map = ((SupportMapFragment) getSupportFragmentManager() 
       .findFragmentById(R.id.map)).getExtendedMap(); 

     // Check if we were successful in obtaining the map. 
     if (map != null) { 
      setUpMap(); 
     } 
    } 
} 

private void setUpMap() { 
    fixMapControlLocations(); 
    ..... 
} 

private void fixMapControlLocations() { 
    SupportMapFragment mapFragment = (SupportMapFragment) getSupportFragmentManager() 
      .findFragmentById(R.id.map); 
    int actionBarHeight = 0; 
    TypedValue tv = new TypedValue(); 
    if (getTheme().resolveAttribute(android.R.attr.actionBarSize, tv, true)) 
    { 
     actionBarHeight = TypedValue.complexToDimensionPixelSize(tv.data,getResources().getDisplayMetrics()); 
    } 

    View myLocationParent = ((View)mapFragment.getView().findViewById(1).getParent()); 
    View myLocationParentParent = ((View)myLocationParent.getParent()); 
    myLocationParentParent.setPadding(0, actionBarHeight, 0, isNarrow()?actionBarHeight:0); 
} 

public boolean isNarrow() { 
    return ResourcesCompat.getResources_getBoolean(getApplicationContext(), 
      R.bool.abs__split_action_bar_is_narrow); 
} 
2

È possibile raggiungere questo obiettivo con la GoogleMap.setPadding() metodo di recente ha aggiunto:

map.setPadding(leftPadding, topPadding, rightPadding, bottomPadding); 

Dalla documentazione API:

Questo metodo consente di definire una regione visibile sulla mappa, per segnalare alla mappa che alcune parti della mappa attorno ai bordi possono essere oscurate, impostando il riempimento su ciascuno dei quattro bordi della mappa. Le funzioni della mappa saranno adattate al padding. Ad esempio, i controlli di zoom, la bussola, le informazioni sul copyright e il logo di Google verranno spostati per adattarsi all'interno della regione definita, movimenti di macchina sarà rispetto al centro della regione del visibile, ecc

vedere anche il description of how padding works in GoogleMap.

Problemi correlati