2013-01-20 14 views
7

Ci sono molte domande su questo problema, ma la maggior parte sono troppo specializzate per rispondere alla mia domanda.A che ora del ciclo di vita dell'applicazione è possibile/utilizzare le misurazioni del layout?

Ho un GoogleMap che dico per adattarsi alla sua fotocamera a determinati limiti. Forse non è molto sorprendente, ottengo un errore:

java.lang.IllegalStateException: Map size should not be 0. Most likely, layout has not yet occured for the map view.

Quindi astratto questo problema a qualsiasi View lasciare.

Quando si verifica effettivamente questo evento di 'layout'? onMeasure() non si visualizza nello Activity Lifecycle, ad esempio. Quando è sicuro chiamare il mio metodo che richiede il layout?

risposta

9

EDIT:

Per risolvere questo particolare problen nel Maps API aggiornata, è necessario utilizzare

map.moveCamera(CameraUpdateFactory.newLatLngBounds(Builder.build(), 50)); 

Per qualsiasi altra vista e API Maps precedente

Utilizzare ViewTreeObserver.OnGlobalLayoutListener come nella risposta di Simon.

È inoltre possibile utilizzare View.post() per aggiungere qualcosa alla coda View messaggio, ma non so se il layout è garantito per avere successo alla fine di esso (alcune persone dicono che non lo fa, ma poi even Groupon + Google do it wrong).

Per una mappa frammento:

MapFragment.getView().post(new Runnable(){ 
    run() { 
     ...Use the layout params... 
    } 
} 
+1

Questa non è una risposta alla domanda posta. –

+0

A volte ritorno a questa domanda e penso, perché Glenn Bech ha detto che questa non era una risposta alla domanda posta, mentre io sono quella che l'ha chiesto ** e ** ha risposto. – Maarten

+0

@GlennBech ha ragione, questa risposta non funziona con l'ultima API di Maps. Non è sicuro che il layout sarà finito quando verrà eseguito il 'Runnable'. – gipi

2

Penso che tu intenda fare qualcosa dopo la visualizzazione dell'interfaccia utente.

L'utilizzo di un listener di layout globale ha sempre funzionato bene per me. Ha anche il vantaggio di poter rimisurare le cose se il layout viene modificato, ad es. se qualcosa è impostato su View.GONE o le viste figlio vengono aggiunte/rimosse.

public void onCreate(Bundle savedInstanceState) 
{ 
    super.onCreate(savedInstanceState); 

    // inflate your main layout here (use RelativeLayout or whatever your root ViewGroup type is 
    LinearLayout mainLayout = (LinearLayout) this.getLayoutInflater().inflate(R.layout.main, null); 

    // set a global layout listener which will be called when the layout pass is completed and the view is drawn 
    mainLayout.getViewTreeObserver().addOnGlobalLayoutListener(
    new ViewTreeObserver.OnGlobalLayoutListener() { 
      public void onGlobalLayout() { 
       // at this point, the UI is fully displayed 
      } 
    } 
); 

setContentView(mainLayout); 

http://developer.android.com/reference/android/view/ViewTreeObserver.OnGlobalLayoutListener.html

1

userei onWindowFocusChanged(boolean). Basta controllare se la finestra delle attività appena ricevuto l'attenzione

@Override 
public void onWindowFocusChanged(boolean hasFocus) 
{ 
    super.onWindowFocusChanged(hasFocus); 

    if(hasFocus) 
    { 
     // Ask for any view size here 
    } 
} 
16

Come dice la documentazione, è necessario utilizzare questo

mapa.moveCamera(CameraUpdateFactory.newLatLngBounds(Builder.build(), 
        this.getResources().getDisplayMetrics().widthPixels, 
        this.getResources().getDisplayMetrics().heightPixels, 
        50)); 

Dove si tratta di un'attività, invece

mapa.moveCamera(CameraUpdateFactory.newLatLngBounds(Builder.build(), 
        50)); 

Questo funziona per me .

La documentazione

Note: Only use the simpler method newLatLngBounds(boundary, padding) to generate a CameraUpdate if it is going to be used to move the camera after the map has undergone layout. During layout, the API calculates the display boundaries of the map which are needed to correctly project the bounding box. In comparison, you can use the CameraUpdate returned by the more complex method newLatLngBounds(boundary, width, height, padding) at any time, even before the map has undergone layout, because the API calculates the display boundaries from the arguments that you pass.

+0

Ricevo ancora il problema utilizzando il codice indicato. Sto usando la chiamata in un 'FragmentActivity'. Potrei aver bisogno di rifattorizzare il mio codice in modo da assicurarmi che venga chiamato dopo che il layout è stato inizializzato correttamente. – theblang

+0

Il mio problema era che stavo cercando di usare 'moveCamera' in' onConnected', che veniva chiamato quando ho chiamato, in 'onResume',' locationClient.connect() '. Secondo il funzionario 'MyLocationDemoActivity' negli esempi, hanno solo' requestLocationUpdates' in 'onConnected', quindi uso' moveCamera' in 'onLocationChanged'. L'unico problema minore è che c'è un breve momento in cui la mappa è altrove prima che si aggiorni. – theblang

+1

@FranciscoHernandez Mi piace questa soluzione. funziona bene specialmente quando si apre il backstack e si deve reinizializzare la mappa – Alan

Problemi correlati