Map v2 SupportMapFragment inside Viewpager

Graham Smith picture Graham Smith · Dec 6, 2012 · Viewed 9.8k times · Source

Background

I have successfuflly added the new map api v2.0 to a ViewPager and the map loads fine. I am using the FragmentViewPager. I run into trouble however when trying to add markers as I cannot get the Fragment by tag as the ViewPager I am using is from the compatibility library and defined in XML, and this "hides" the tag from me.

The Question

How can I load the new Map v2 with markers SupportMapFragment into a ViewPager that uses a FragmentPagerAdapter.

My Attempt

So in my nievety I thought could create an elegant solution by extending the SupportMapFragment into a new class that does the following:

  1. Add a new constructor that takes GoogleMapOptions and List<MarkerOptions> . This effectively calls the existing constructor that just takes GoogleMapsOptions and then store my list of markers inside a private property of the new class.
  2. Override GetMap() - check if it is null and if it is not add the markers to the map that we loaded earlier on to the map and finally return it.

My thoughts were that my extension could be highly reusable and abstracts anything map related to one place and allows my activities to create the new MapFragment by newInstance(myGoogleMapOptions, myMarkers).

Ok so the issue. Part 1 seems to work fine however during debugging I cannot get the overridden GetMap() method to be called. In fact I have tried overriding most of the usual methods that fragments have and none of them get called. Is there something weird going on with the SupportMapFragmemt, I tried to find the source for it to no avail to check for myself.

Update

I realised why I wasn't getting my overridden methods called. It was because I was returning the standard SupportMapFragment rather than MyMapFragment. That said I cannot call super from a static method and I cannot cast from a base class to a derived class without exception.

Edit Here is the class

public class MyMapFragment extends SupportMapFragment {

    private static List<MarkerOptions> mMarkers;

    public static SupportMapFragment newInstance(GoogleMapOptions options, List<MarkerOptions> markers)
    {
        SupportMapFragment fragment = newInstance(options);

        mMarkers = markers;

        return fragment;

    }

            //have tried Overriding several methods including getMap()...

    @Override
    public void onResume ()
    {
        GoogleMap mMap = super.getMap();
        //add the markers
        if(mMap != null)
        {
            for(MarkerOptions marker : mMarkers)
            {
                mMap.addMarker(marker);
            }
        }

    }

}

Answer

Venator85 picture Venator85 · Dec 9, 2012

Just tried like this and it works.

public class MyMapFragment extends SupportMapFragment {

    private List<MarkerOptions> mMarkers;

    public static MyMapFragment create(GoogleMapOptions options, ArrayList<MarkerOptions> markers) {
        MyMapFragment fragment = new MyMapFragment();

        Bundle args = new Bundle();
        args.putParcelable("MapOptions", options); //obtained by decompiling google-play-services.jar
        args.putParcelableArrayList("markers", markers);
        fragment.setArguments(args);

        return fragment;
    }

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

        // Hacky and ugly but it works
        ArrayList<Parcelable> list = getArguments().getParcelableArrayList("markers");
        mMarkers = new ArrayList<MarkerOptions>(list.size());
        for (Parcelable parcelable : list) {
            mMarkers.add((MarkerOptions) parcelable);
        }
    }

    @Override
    public void onResume() {
        super.onResume();
        GoogleMap mMap = super.getMap();
        //add the markers
        if (mMap != null) {
            for (MarkerOptions marker : mMarkers) {
                mMap.addMarker(marker);
            }
        }
    }
}