2014-10-13 22 views
6

Mam przypadek użycia, w którym lista i widok mapy mają dość tę samą podstawę kodu i pokazują te same dane. Nie mogę ich rozdzielić, używając funkcji ListFragment i MapFragment jako rodzica.Jak zachować widok mapy wewnątrz fragmentu?

Więc zrobiłem fragment zawierający obie odsłony:

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

Użytkownik może przełączać się między listy i widoku mapy. Działa to bardzo dobrze, mimo że widok mapy nie może zachować swoich znaczników przy zmianach konfiguracji. Po obróceniu ekranu widok mapy uzyskuje stan początkowy bez znaczników i bez powiększenia. Wszystkie znaczniki, które wcześniej dodano, zniknęły. Kiedy użyłem MapFragment, nie miałem tego problemu, on sam zachował się.

Rozebrani kod:

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

Jakieś pomysły jak rozwiązać ten problem? Jednym rozwiązaniem byłoby zastąpienie wszystkich znaczników. Chciałbym jednak wiedzieć, czy istnieje inne podejście.

Odpowiedz

3

Marker Obiekt nie może zostać zatrzymany poprzez zmiany konfiguracji, ponieważ nie implementuje interfejsu Parcelable lub Serializable.

Można jednak zachować obiekt MarkerOptions, ponieważ jest to Parcelable, a następnie ponownie utworzyć jego numer Marker. Można mieć pole klasy typu MarkerOptions dla każdego z Marker s, a następnie ponownie wypełnić mapę na zmiany konfiguracji (na przykład w onSaveInstanceState):

mapView.getMap().addMarker(MyMarkerOptions); 

Innym sposobem byłoby zapisać Marker sek w HashMap i używaj ich ponownie przy zmianach konfiguracji.

Here is another full example, która używa Parcelable LatLng punktów do utrwalenia Markers.

Ten przykład działa, więc dodając znacznik, dodaje on również odpowiednie współrzędne do obiektu ArrayList jako LatLng. Następnie po zmianie konfiguracji, ArrayList zostaje zapisany w obiekcie Bundle w obiektach onSaveInstanceState, a obiekty zostają pobrane w onCreate. uwaga


OP:

Poszedłem więc z roztworem do wdrożenia onSaveInstanceState i upuść setRetainInstance(true). Korzyścią jest to, że sam mogę zachować mapę. Jednak wadą jest to, że mapa musi być w pełni zainicjalizowana przy każdej zmianie konfiguracji, która sprawia, że ​​aplikacja jest wolna przez 1 lub 2 sekundy na przykład na komputerze. obrót ekranu. Ale jestem z tym w porządku.

+1

Zakładam, że muszę usunąć setRetainInstance, ponieważ onSaveInstanceState nie zostanie wywołany? –

+0

To prawda :) – nem035

+0

@artworkad シ fajnie, cieszę się, że udało ci się znaleźć odpowiednie rozwiązanie. Ten problem jest dość znany i nie ma bezpośredniego rozwiązania, niestety, https://code.google.com/p/gmaps-api-issues/issues/detail?id=4650 innych niż proponowane przeze mnie rozwiązania. – nem035