Android: how to notify Activity when Fragments views are ready?

Gal Ben-Haim picture Gal Ben-Haim · Feb 21, 2013 · Viewed 29.3k times · Source

I'm using Google Maps API V2 in an activity wih drop down navigation where the map is on the second position.

I'm adding the map pragmatically like:

mMapFragment = supportMapFragment.newInstance();
getSupportFragmentManager()
        .beginTransaction()
        .replace(R.id.placeHolder, mMapFragment, TAG_MAP)
        .commit(); 

I want to get the GoogleMap ovject, as the documentation https://developers.google.com/maps/documentation/android/map say it should be done with mMapFragment.getMap(), but it returns null.

according to http://developer.android.com/reference/com/google/android/gms/maps/SupportMapFragment.html it returns null if the Fragment hasn't gone through the onCreateView lifecycle event.

how can I know whenever the fragment is ready ?

EDIT: I found this How do I know the map is ready to get used when using the SupportMapFragment?

Overriding onActivityCreated seems like a solution, but then I'll have to instantiate the fragment through a constructor and not with newInstance(), does it make any difference ?

Answer

Kirk picture Kirk · Feb 21, 2013

My preferred method is to use a callback to get a signal from a Fragment. Also, this is the recommended method proposed by Android at Communicating with the Activity

For your example, in your Fragment, add an interface and register it.

public static interface OnCompleteListener {
    public abstract void onComplete();
}

private OnCompleteListener mListener;

public void onAttach(Context context) {
    super.onAttach(context);
    try {
        this.mListener = (OnCompleteListener)context;
    }
    catch (final ClassCastException e) {
        throw new ClassCastException(context.toString() + " must implement OnCompleteListener");
    }
}

Now implement this interface in your Activity

public class MyActivity extends FragmentActivity implements MyFragment.OnCompleteListener {
    //...

    public void onComplete() {
        // After the fragment completes, it calls this callback.
        // setup the rest of your layout now
        mMapFragment.getMap()
    }
}

Now, whatever in your Fragment signifies that it's loaded, notify your Activity that it's ready.

@Override
protected void onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
    // create your fragment
    //...

    // signal that you're done and tell the Actvity to call getMap()
    mListener.onComplete();
}

EDIT 2017-12-05 onAttach(Activity activity) is deprecated, use onAttach(Context context) instead. Code above adjusted.