In the onCreate
method, I am making use of the SupportMapFragment
to show a map.
SupportMapFragment fragment = new SupportMapFragment(); getSupportFragmentManager().beginTransaction() .add(android.R.id.content, fragment).commit();
In conjunction to this, I would like to add a marker. The problem is when the call to getMap
is null, when can I try again? Is there an event I can register for or is my approach in and of itself wrong?
mMap = ((SupportMapFragment)(getSupportFragmentManager().findFragmentById(R.id.map))).getMap(); if(mMap == null) //what do I do here?
The map is in fact displaying on the phone however I appear to be having no luck in obtaining the reference to add markers.
UPDATE:
The reason I was creating the SupportMapFragment
via the constructor is because the typical setContentView
was crashing and did not work. This put me in the predicament where I could not obtain my reference in the onCreate
method since I was in fact creating the SupportMapFragment
at that time. In further investigation, it appears my setContentView
issue was a byproduct of not having both the Google-play-services jar AND the module/src set up as part of the overall project. Upon doing BOTH of these, setContentView
now works and I can obtain the reference via getMap()
as I would expect.
lots.xml...
<?xml version="1.0" encoding="utf-8"?> <fragment xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/map" android:name="com.google.android.gms.maps.SupportMapFragment" android:layout_width="match_parent" android:layout_height="match_parent" />
LotsActivity.java...
public class LotsActivity extends FragmentActivity { public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.lots); GoogleMap mMap; mMap = ((SupportMapFragment)(getSupportFragmentManager().findFragmentById(R.id.map))).getMap(); if(mMap == null) //this should not occur now }
This method can be called from both the onCreate() and onResume() stages to ensure that the map is always available. private void setUpMapIfNeeded() { // Do a null check to confirm that we have not already instantiated the map. if (mMap == null) { mMap = ((MapFragment) getFragmentManager().
Callback interface for when the map is ready to be used. Once an instance of this interface is set on a MapFragment or MapView object, the onMapReady(GoogleMap) method is triggered when the map is ready to be used and provides a non-null instance of GoogleMap .
public class SupportMapFragment extends Fragment. A Map component in an app. This fragment is the simplest way to place a map in an application. It's a wrapper around a view of a map to automatically handle the necessary life cycle needs.
EDIT: getMap
is deprecated now
The problem is when the call to getMap is null, when can I try again?
That depends upon the nature of the problem.
If you set up the SupportMapFragment
via the <fragment>
element in the layout, you can call getMap()
successfully in onCreate()
. But, if you create the SupportMapFragment
via the constructor, that's too soon -- the GoogleMap
does not yet exist. You can extend SupportMapFragment
and override onActivityCreated()
, as getMap()
is ready by then.
However, getMap()
can also return null
for a bigger problem, such as Google Play Services not being installed. You would need to use something like GooglePlayServicesUtil.isGooglePlayServicesAvailable()
to detect this condition and deal with it however you wish.
I ended up extending the SupportMapFragment class and using a callback. The code is here:
public class MySupportMapFragment extends SupportMapFragment { public MapViewCreatedListener itsMapViewCreatedListener; // Callback for results public abstract static class MapViewCreatedListener { public abstract void onMapCreated(); } @Override public View onCreateView (LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { View view = super.onCreateView(inflater, container, savedInstanceState); // Notify the view has been created if( itsMapViewCreatedListener != null ) { itsMapViewCreatedListener.onMapCreated(); } return view; } }
I would rather have used an interface and override the onAttach(activity) method, but in my case, I didn't want the callback to go back to my MainActivity. I wanted it to return to an instance of Fragment. (The GoogleMap was essentially a fragment inside a fragment) I setup the callback and programmatically loaded the map with this. I would like to have set itsMapViewCreatedListener inside the constructor of MySupportMapFragment, but using anything other than parameterless constructors is discouraged.
itsMySupportMapFragment = new MySupportMapFragment(); MapViewCreatedListener mapViewCreatedListener = new MapViewCreatedListener() { @Override public void onMapCreated() { initPlacesGoogleMapCtrl(); } }; itsMySupportMapFragment.itsMapViewCreatedListener = mapViewCreatedListener; FragmentTransaction transaction = getActivity().getSupportFragmentManager().beginTransaction(); transaction.replace(R.id.mapFragmentContainer, itsMySupportMapFragment); transaction.addToBackStack(null); transaction.commit();
And then, when I got the call back, I could get the map; no more null!
public void initPlacesGoogleMapCtrl() { // Map ready, get it. GoogleMap googleMap = itsMySupportMapFragment.getMap(); // Do what you want... }
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With