user1610177
user1610177

Reputation: 177

android GoogleMap is null, displays fine but can't add markers/polylines

I have a GoogleMap which displays fine (within a SupportMapFragment) and uses the GoogleMapOptions for the target camera location. However, I am unable to add markers/polylines to the GoogleMap. Here is the method for creating the map:

private void createMap(List<LatLng> latLngs) {

    if(map == null) {
        GoogleMapOptions options = new GoogleMapOptions();
        mapFragment = SupportMapFragment.newInstance(options);
        map = mapFragment.getMap();

        float zoom = 13;
        CameraPosition cameraP = new CameraPosition(latLngs.get(0), zoom, 0, 0);
        options.camera(cameraP);


        //TODO MAP IS NULL - SORT OUT!
        // check it has been instantiated
        if (map != null) {
            Log.d(TAG, "map is not null");
            map.clear();
            //Calculate target zoom, based on trip size
            map.animateCamera(CameraUpdateFactory
                    .newCameraPosition(cameraP));
            // Add LatLngs to polyline

            PolylineOptions poly = new PolylineOptions().color(Color.RED);
            MarkerOptions startMarker = new MarkerOptions()
                    .position(latLngs.get(0)).title("Start");
            MarkerOptions endMarker = null;
            if(latLngs.size() > 1) {
             endMarker = new MarkerOptions().position(
                    latLngs.get(latLngs.size() - 1)).title("End");  
            }

            for (LatLng latLng : latLngs) {
                poly.add(latLng);
            }

            map.addPolyline(poly);
            map.addMarker(startMarker);
            map.addMarker(endMarker);

        }


        ft = getSupportFragmentManager().beginTransaction();
        ft.add(R.id.trip_summary_map_container, mapFragment);
        ft.commit();
    }
}

As you can see from the inline comments, the map is still null (although it is displaying and using the options). Just can't add things to it. I assume I am not instantiating it properly?

The Activity extends FragmentActivity, and I have set up all the necessary stuff for using the Maps API.

Thank you for any help.

Upvotes: 0

Views: 1714

Answers (3)

Rub&#233;n Illodo Brea
Rub&#233;n Illodo Brea

Reputation: 321

EDIT: I have posted a new answer with the solution I prefer to use now.

I had the same problem some days ago and I solved it extending SupportMapFragment class so that it executes a callback method once the map is finally ready.

public class ExtendedSupportMapFragment extends SupportMapFragment {

    public static interface MapReadyListener {
        public void mapIsReady(GoogleMap map);
    }

    @Deprecated
    public static SupportMapFragment newInstance() {
        return null;
    }

    @Deprecated
    public static SupportMapFragment newInstance(GoogleMapOptions options) {
        return null;
    }

    public static ExtendedSupportMapFragment newInstance(MapReadyListener mapReadyListener) {
        ExtendedSupportMapFragment fragment = new ExtendedSupportMapFragment();
        fragment.mapReadyListener = mapReadyListener;

        return fragment;
    }

    private MapReadyListener mapReadyListener;

    @Override
    public void onActivityCreated(Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);
        if (mapReadyListener != null)
            mapReadyListener.mapIsReady(getMap());
    }

}

Then you just need to do something like this:

public class RutaMapaFragment extends SherlockFragment implements ExtendedSupportMapFragment.MapReadyListener {

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        fragmentMapa = ExtendedSupportMapFragment.newInstance(RutaMapaFragment.this);
    }

    ...

    @Override
    public void mapIsReady(GoogleMap map) {
        //Do whatever you want with your map.
    }

}

Upvotes: 2

Rub&#233;n Illodo Brea
Rub&#233;n Illodo Brea

Reputation: 321

So, time has passed and all. The fact is that I don't use the solution in my previous answer anymore, but prefer to use a ViewTreeObserver instead. The following code shows a rather simple fragment with a SupportMapFragment being added to it.

The method createMap() adds the SupportMapFragment and then executes setupMap(), but only via a OnGlobalLayoutListener that will basically be executed once the map is actually ready. Of course, this listener is removed immediately—there's no need to keep it there any longer.

public class MyMapFragment extends Fragment {

    private View mMapContainer;
    private SupportMapFragment mMapFragment;
    private GoogleMap mMap;

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
            Bundle savedInstanceState) {
        View view = inflater.inflate(/* ... */);
        // ...

        mMapContainer = view.findViewById(R.id.map_fragment_container);
        createMap();

        return view;
    }

    private void createMap() {
        mMapFragment = new SupportMapFragment();

        getFragmentManager().beginTransaction()
                .replace(R.id.map_fragment_container, mMapFragment)
                .commit();

        mMapContainer.getViewTreeObserver()
                .addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {

                    @TargetApi(Build.VERSION_CODES.JELLY_BEAN)
                    @Override
                    public void onGlobalLayout() {
                        if (Build.VERSION.SDK_INT > Build.VERSION_CODES.JELLY_BEAN) {
                            mMapContainer.getViewTreeObserver().removeOnGlobalLayoutListener(this);
                        } else {
                            mMapContainer.getViewTreeObserver().removeGlobalOnLayoutListener(this);
                        }

                        mMap = mMapFragment.getMap();
                        setupMap();
                    }

                });
    }

    private void setupMap() {
        mMap.setMyLocationEnabled(true);
        // ...
    }

}

Upvotes: 1

GrIsHu
GrIsHu

Reputation: 23638

Try to add the Marker & PolyLines in the map using below code:

GoogleMap mMap;
static final CameraPosition BONDI =
        new CameraPosition.Builder().target(new LatLng(-33.891614, 151.276417))
                .zoom(15.5f)
                .bearing(300)
                .tilt(50)
                .build();
changeCamera(CameraUpdateFactory.newCameraPosition(BONDI));
    mMap.addMarker(new MarkerOptions().position(new LatLng(-33.891614, 151.276417)).title("Bondi"));
 private void changeCamera(CameraUpdate update) {
    changeCamera(update, null);
    }
/**
 * Change the camera position by moving or animating the camera depending on the state of the
 * animate toggle button.
 */
private void changeCamera(CameraUpdate update, CancelableCallback callback) {
    boolean animated = ((CompoundButton) findViewById(R.id.animate)).isChecked();
    if (animated) {
        mMap.animateCamera(update, callback);
    } else {
        mMap.moveCamera(update);
    }
}

Add the PolyLines as below:

 // A simple polyline with the default options from Melbourne-Adelaide-Perth.
    mMap.addPolyline((new PolylineOptions())
            .add(BONDI));

Upvotes: 0

Related Questions