How to reuse SupportMapFragment inside other Fragment
android-maps, android-maps-extensions, android-maps-v2
Solution
Instead of using MapFragment we can use MapView, that exists in androidmapsextensions too. And it can be reused.
Since adding MapView programatically, need to call mapView.onCreate(bundle)
private MapView mapView;
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
super.onCreateView(inflater, container, savedInstanceState);
View view = inflater.inflate(R.layout.fragment_map, container, false);
if (mapView != null) {
ViewGroup parentViewGroup = (ViewGroup) mapView.getParent();
if (parentViewGroup != null) {
parentViewGroup.removeView(mapView);
}
} else {
mapView = new MapView(getActivity());
mapView.onCreate(Bundle.EMPTY); //need if programmatically add
}
((ViewGroup)view.findViewById(R.id.container)).addView(mapView);
mapView.getExtendedMapAsync(new OnMapReadyCallback() {
public void onMapReady(GoogleMap googleMap) {
setUpMap(GoogleMap);
}
});
}
Or if we don't need any setup for reused mapView
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
super.onCreateView(inflater, container, savedInstanceState);
View view = inflater.inflate(R.layout.fragment_map, container, false);
boolean needSetupMap = true;
if (mapView != null) {
ViewGroup parentViewGroup = (ViewGroup) mapView.getParent();
if (parentViewGroup != null) {
parentViewGroup.removeView(mapView);
needSetupMap = false;
}
} else {
mapView = new MapView(getActivity());
mapView.onCreate(Bundle.EMPTY);
}
((ViewGroup)view.findViewById(R.id.container)).addView(mapView);
if (needSetupMap) {
mapView.getExtendedMapAsync(new OnMapReadyCallback() {
public void onMapReady(GoogleMap googleMap) {
setUpMap(GoogleMap);
}
});
}
}
Problem
I just switched to the newest version of android-maps-extensions (2.2.0) together with newest Play Services (6.5.87) and support library (21.0.3). And now I can't reuse my MapFragment. I have MainActivity with NavigationDrawer. One of the fragments is fragment with GoogleMap fragment inside. When I switch between fragments in NavigationDrawer they recreate themselves. Previously I used very simply solution for this. I used already inflated view: ``` public View onCreateView(LayoutInflater inflater, ViewGroup container, final Bundle savedInstanceState) { super.onCreateView(inflater, container, savedInstanceState); if (view != null) { ViewGroup parent = (ViewGroup) view.getParent(); if (parent != null) { parent.removeView(view); } return view; } view = inflater.inflate(R.layout.fragment_map, container, false); SupportMapFragment mapFragment = SupportMapFragment.newInstance(); FragmentTransaction transaction = getChildFragmentManager().beginTransaction(); transaction.add(R.id.container, mapFragment).commit(); mapFragment.getExtendedMapAsync(new OnMapReadyCallback() { public void onMapReady(GoogleMap googleMap) { map = googleMap; setupMap(); } }); return view; } ``` But now it doesn't work. Map doesn't show when this fragment opens second time. I can just throw out this ugly code ``` if (view != null) { ViewGroup parent = (ViewGroup) view.getParent(); if (parent != null) { parent.removeView(view); } return view; } ``` And always recreate view with inside. But I have thousands of Markers (of course with awesome Clustering) and it takes many time to repaint them. I know it's not the problem of extensions-library, Google Maps have the same behavior. But maybe you know right decision?