How to keep the map view inside the fragment?

I have a use case when the list and map view share the same code base and show the same data. Therefore, I cannot separate them using ListFragment and MapFragment as parents.

So, I made a fragment containing both views:

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

The user can switch between the list and the map view. This works very well, even though the map display cannot retain its markers when changing the configuration. When the screen rotates, the map view gets its initial state without markers and without scaling. All markers where previously added have disappeared. When I used MapFragment, I did not have this problem, it seems to be preserved.

Code taken:

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

Any ideas how to solve this problem? One solution would be to replace all markers. However, I would like to know if there is another approach.

+6
source share
1 answer

Marker object cannot be saved through configuration changes because it does not implement the Parcelable or Serializable interface.

However, you can save MarkerOptions because it is Parcelable , and then recreate Marker . You can have a class field of type MarkerOptions for each of your Marker , and then re-fill the map when you change the configuration (for example, onSaveInstanceState ):

 mapView.getMap().addMarker(MyMarkerOptions); 

Another way would be to save your Marker in a HashMap and reuse them when configuration changes.

Here is another full example that uses Parcelable LatLng points to save Markers .

This example works, so when you add a marker, it also adds the appropriate coordinates to the ArrayList object as LatLng . Then, when the configuration is changed, the ArrayList stored in the Bundle object in onSaveInstanceState , and the LatLng objects are obtained in onCreate .


OP Note:

So, I went with a solution for implementing onSaveInstanceState and dropped setRetainInstance(true) . The advantage is that I can save the map myself. However, the disadvantage is that the card must be fully initialized with every configuration change, which makes the application slow for 1 or 2 seconds, for example. screen rotation. But I'm fine with that.

+3
source

Source: https://habr.com/ru/post/976654/


All Articles