2013-01-22 5 views
7

Ho un problema con un frammento che incorpora SuportMapFragment dalla nuova API di Google Maps. Quando viene creato il mio frammento, recupera alcuni dati in un AsyncTask a partire dal metodo onResume. Mentre ciò accade, MapFragment rimane fuori dallo schermo, invece viene visualizzata una barra di avanzamento.Perché GoogleMap.animateCamera() si arresta in modo anomalo dopo onGlobalLayout()?

Quando il AsyncTask è completato, mi registro con l'evento onGlobalLayout di mapView. Quindi visualizzo il frammento, che consente di visualizzare e strutturare la vista della mappa. onGlobalLayout viene attivato e l'animazione inizia.

Questo ha funzionato bene per un po 'di tempo, fino a quando ho iniziato a ottimizzare le operazioni nella raccolta dati AsyncTask per completare quasi istantaneamente. Ora l'app si arresta spesso in modo anomalo all'avvio, più spesso in Release che in Debug, motivo per cui penso di avere a che fare con una condizione di guida che non conosco.

L'eccezione si legge:

Dimensioni mappa non deve essere 0. Molto probabilmente, il layout non ha ancora verificato per la visualizzazione della mappa.

Qualsiasi approfondimento è molto apprezzato.

Per riferimento: Questo è il codice che sembra causare l'incidente:

// Hide status UI 
this.progressBar.setVisibility(View.INVISIBLE); 
this.statusTextView.setVisibility(View.INVISIBLE); 

// Update state 
this.uraDataDownloadFinished = true; 

// Schedule map translation to occur when layout is complete 
final View mapView = this.mapFragment.getView(); 
if (mapView.getViewTreeObserver().isAlive()) 
{ 
    mapView.getViewTreeObserver().addOnGlobalLayoutListener(new OnGlobalLayoutListener() 
    { 
     @SuppressWarnings("deprecation") 
     @SuppressLint("NewApi") // We check which build version we are using. 
     @Override 
     public void onGlobalLayout() 
     { 
      Log.d(TAG, "onGlobalLayout()"); 
      if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN) 
      { 
       mapView.getViewTreeObserver().removeGlobalOnLayoutListener(this); 
      } 
      else 
      { 
       mapView.getViewTreeObserver().removeOnGlobalLayoutListener(this); 
      } 

      // here we crash 
      this.map.animateCamera(
        CameraUpdateFactory.newLatLngBounds(
          LatLngBounds.builder() 
           .include(topLeft) 
           .include(topRight) 
           .include(bottomLeft) 
           .include(bottomRight) 
           .build(), 
          0), 
        durationMs, 
        null); 
     } 
    }); 
} 

// Show map (which will eventually trigger onGlobalLayout) 
this.getFragmentManager().beginTransaction().show(this.mapFragment).commit(); 
this.mapFragment.getMap().setOnCameraChangeListener(this); 

Grazie mille!

risposta

5

Non sono sicuro, ma poiché stai usando AsyncTask probabilmente stai cercando di ottenere i limiti della mappa prima che la mappa sia stata sottoposta a layout.

È possibile vedere lo documentation, suggerisce invece di utilizzare newLatLngBounds(boundary, width, height, padding).

+0

Grazie, che funziona. Poiché la mappa riempie completamente un contenitore di layout, posso invece usare le sue dimensioni. Tuttavia, la mia domanda rimane. Dato che sto aspettando 'onGlobalLayout()', non dovrei incorrere in questo problema, dovrei? – Chris

+0

No, non la penso così, devi aspettare che le mappe abbiano subito il layout. – jgonza73

+0

... o modifica CameraOptions senza limiti di mappa – jgonza73

3

provate questo, per me funziona:

map.setOnCameraChangeListener(new OnCameraChangeListener() { 

    @Override 
    public void onCameraChange(CameraPosition arg0) { 
     // Move camera. 
     map.moveCamera(CameraUpdateFactory.newLatLngBounds(builder.build(), 10)); 
     // Remove listener to prevent position reset on camera move. 
     map.setOnCameraChangeListener(null); 
    } 
});