Thanks, you finally gave me a clue to initialize the Map programatically, how stupid I oversaw it :)
Well, sometimes there is no option to use MapFragment (or SupportMapFragment alike), i.e. when you want to use the map from a fragment! This is actually a very common case when working with tabs (ActionBar) where the pattern is to use fragments. So you've got your own fragment per tab and in that fragment for a map you want to inflate your layout which contains a fragment for the MapFragment, et voila - good luck!
Now, according to the MapView specs it is no way said that using of the MapView is discouraged or deprecated, so why should I not use it? I did not want hacks in maintaining nested fragments without having support from SDK ( even the recent support lib v13 seems to have bugs and nested fragments from layout are not supported ), so using MapView turned for me into KISS.
Below is my CustomMapFragment I use with layout inflation (allowing complex layout) and embedded map, you're welcome to use it. You may also want to extend the Fragment from support-lib rather than SDK.
The onCreateView() method inflates the layout (just provide you're own) and expects the layout to have viewgroup (relativelayout,linearlayout,etc) with id "mapViewHolder" where the mapView will be attached to upon layout creation. The activity has to implement CustomMapFragment.Handler interface, otherwise ClassCastException will be thrown.
import android.app.Activity;
import android.app.Fragment;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Toast;
import com.google.android.gms.common.GooglePlayServicesNotAvailableException;
import com.google.android.gms.maps.GoogleMap;
import com.google.android.gms.maps.MapView;
import com.google.android.gms.maps.MapsInitializer;
import R;
public class AppMapFragment extends Fragment {
/*
* to interact with activity
*/
public static interface Handler {
void onMapResume(GoogleMap map);
}
private Handler handler;
private MapView mapView;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
try {
// initialize explicitely, since we're working with MapView (not MapFragment)
MapsInitializer.initialize(getActivity());
this.mapView = new MapView(getActivity());
this.mapView.onCreate(savedInstanceState);
} catch (GooglePlayServicesNotAvailableException e) {
Toast.makeText(getActivity(), "Please install Google Play Store and retry again!", Toast.LENGTH_LONG).show();
getActivity().finish();
}
}
@Override
public void onResume() {
super.onResume();
this.mapView.onResume();
this.handler.onMapResume(this.mapView.getMap());
}
@Override
public void onPause() {
super.onPause();
this.mapView.onPause();
}
@Override
public void onDestroy() {
super.onDestroy();
this.mapView.onDestroy();
}
@Override
public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
this.mapView.onSaveInstanceState(outState);
}
@Override
public void onLowMemory() {
super.onLowMemory();
this.mapView.onLowMemory();
}
@Override
public void onAttach(Activity activity) {
super.onAttach(activity);
try {
this.handler = (Handler) activity;
} catch (ClassCastException e) {
throw new ClassCastException("Your activity has to implement the interface " + this.handler.getClass().getName());
}
}
public AppMapFragment() {
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_results_map, container, false);
((ViewGroup) rootView.findViewById(R.id.mapViewHolder)).addView(this.mapView);
return rootView;
}
}