2014-10-13 11 views
6

Ho un caso d'uso in cui una lista e una vista mappa condividono lo stesso codice base e mostrano gli stessi dati. Quindi non posso separarli usando ListFragment e MapFragment come genitore.Come mantenere una vista mappa all'interno di un frammento?

così ho fatto un frammento che contiene entrambe le viste:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" 
    android:layout_width="match_parent" 
    android:layout_height="match_parent"> 

    <android.support.v7.widget.RecyclerView 
     android:id="@+id/list" 
     android:layout_width="match_parent" 
     android:layout_height="match_parent" 
     android:visibility="invisible"/> 

    <com.google.android.gms.maps.MapView 
     android:id="@+id/mapView" 
     android:layout_width="match_parent" 
     android:layout_height="match_parent"/> 

</RelativeLayout> 

L'utente può passare dalla lista e guarda la mappa. Funziona molto bene nonostante il fatto che la vista mappa non possa mantenere i suoi marcatori sulle modifiche di configurazione. Quando lo schermo viene ruotato, la vista della mappa diventa il suo stato iniziale senza marcatori e senza zoom. Tutti i marcatori che sono stati aggiunti in precedenza. Quando ho usato MapFragment non avevo questo problema, è stato conservato da solo.

ridotta codice:

public class ListAndMapFragment extends Fragment { 

    private MapView mapView; 

    public ListAndMapFragment() {} 

    @Override 
    public void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setRetainInstance(true); 
    } 

    @Override 
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle arguments) { 
     super.onCreateView(inflater, container, arguments); 
     View root = inflater.inflate(R.layout.fragment_pillar_list, container, false); 
     mapView = (MapView) root.findViewById(R.id.mapView); 

     if (arguments == null) { 
      mapView.onCreate(null); 
      MapsInitializer.initialize(this.getActivity()); 
     } 

     return root; 
    } 

    private GoogleMap getMap() { 
     return mapView.getMap(); 
    } 

    @Override 
    public void onResume() { 
     mapView.onResume(); 
     super.onResume(); 
    } 

    @Override 
    public void onDestroy() { 
     super.onDestroy(); 
     mapView.onDestroy(); 
    } 

    @Override 
    public void onLowMemory() { 
     super.onLowMemory(); 
     mapView.onLowMemory(); 
    } 
} 

Delle idee come risolvere questo problema? Una soluzione sarebbe quella di sostituire tutti i marcatori. Tuttavia mi piacerebbe sapere se c'è un altro approccio.

risposta

3

Marker l'oggetto non può essere trattenuto tramite modifiche di configurazione perché non implementa l'interfaccia Parcelable o Serializable.

Tuttavia, è possibile mantenere l'oggetto MarkerOptions perché è Parcelable e quindi ricreare il numero Marker da esso. Si può avere un campo di classe di tipo MarkerOptions per ciascuno dei vostri Marker s e poi ripopolare la mappa su modifiche di configurazione (ad esempio in onSaveInstanceState):

mapView.getMap().addMarker(MyMarkerOptions); 

Un altro modo sarebbe quello di salvare le Marker s in un HashMap e riutilizzarli sulle modifiche di configurazione.

Here is another full example che utilizza Parcelable LatLng punti per persistere Markers.

L'esempio funziona in modo che quando si aggiunge un marcatore si aggiungono anche le coordinate corrispondenti a un oggetto LatLng come LatLng. Quindi, in caso di modifica della configurazione, ArrayList viene salvato in un oggetto Bundle in onSaveInstanceState e gli oggetti LatLng vengono recuperati in onCreate. nota


PO:

così sono andato con la soluzione per implementare onSaveInstanceState e rilasciare setRetainInstance(true). Il vantaggio è che posso mantenere la mappa da solo. Tuttavia lo svantaggio è che la mappa deve essere completamente inizializzata su ogni cambiamento di configurazione che rende l'app lenta per 1 o 2 secondi, ad es. rotazione dello schermo. Ma sto bene con questo.

+1

Suppongo di dover rimuovere setRetainInstance perché onSaveInstanceState non verrà chiamato? –

+0

Che è corretto :) – nem035

+0

@artworkad シ cool, sono contento che sei riuscito a trovare una soluzione adeguata. Questo problema è in realtà piuttosto noto e purtroppo non esiste una soluzione diretta https://code.google.com/p/gmaps-api-issues/issues/detail?id=4650 oltre alle varianti di soluzioni che ho suggerito qui. – nem035