web-dev-qa-db-fra.com

Android: comment notifier l'activité lorsque les vues Fragments sont prêtes?

J'utilise Google Maps API V2 dans le cadre d'une activité de navigation déroulante dans laquelle la carte se trouve en deuxième position.

J'ajoute la carte de manière pragmatique comme:

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

Je souhaite obtenir l'ovject GoogleMap en tant que documentation https://developers.google.com/maps/documentation/Android/map dis que cela devrait être fait avec mMapFragment.getMap(), mais renvoie null.

selon http://developer.Android.com/reference/com/google/Android/gms/maps/SupportMapFragment.html elle renvoie la valeur null si le fragment n'a pas traversé l'événement de cycle de vie onCreateView.

comment puis-je savoir quand le fragment est prêt?

EDIT: J'ai trouvé ceci Comment savoir si la carte est prête à être utilisée lors de l'utilisation de SupportMapFragment?

Remplacer onActivityCreated semble être une solution, mais ensuite, je devrai instancier le fragment via un constructeur et non avec newInstance (), cela fait-il une différence?

23
Gal Ben-Haim

Ma méthode préférée consiste à utiliser un rappel pour obtenir un signal de Fragment. En outre, c’est la méthode recommandée par Android sur Communiquer avec l’Activité

Pour votre exemple, dans votre Fragment, ajoutez une interface et enregistrez-la.

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");
    }
}

Maintenant, implémentez cette interface dans votre 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()
    }
}

Maintenant, quoi que ce soit dans votre Fragment qui signifie qu'il est chargé, informez votre Activity qu'il est prêt.

@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 (activité d'activité) est obsolète , utilisez onAttach (contexte de contexte) à la place. Code ci-dessus ajusté.

40
Kirk

En plus de La réponse de Kirk : puisque public void onAttach(Activity activity) est obsolète, vous pouvez maintenant utiliser simplement:

@Override
public void onAttach(Context context) {
    super.onAttach(context);

    Activity activity;

    if (context instanceof Activity){

        activity=(Activity) context;

        try {
            this.mListener = (OnCompleteListener)activity;
        } catch (final ClassCastException e) {
            throw new ClassCastException(activity.toString() + " must implement OnCompleteListener");
        }
    }
}

Le reste reste le même ... On peut vouloir utiliser (Fragment sender) en tant que paramètre et toujours passer this.

2
Rok Jarc

Si vous voulez le faire sans aucun auditeur:

Ajouter un fragment avec une balise

 supportFragmentManager
                .beginTransaction()
                .add(R.id.pagerContainer, UniversalWebViewFragment.newInstance(UniversalWebViewFragment.YOUTUBE_SERACH_URL+"HD trailers"), 
                "UniversalWebView")
                .disallowAddToBackStack()
                .commit()

Créez une méthode publique dans Hosting Activity class que vous souhaitez appeler après le chargement de fragment. Ici, je rappelle une méthode de mon fragment par exemple

public fun loadURL() {
        val webViewFragment = supportFragmentManager
                              .findFragmentByTag("UniversalWebView") 
                               as UniversalWebViewFragment

        webViewFragment.searchOnYoutube("Crysis Warhead")
    }

Maintenant, dansonViewCreatedMéthode de votre fragment, vous pouvez simplement appeler cette méthode publique d'activité de l'hôte de la manière suivante:

    (activity as HomeActivity ).loadURL()
0
Hitesh Sahu

Je ne suis pas sûr de bien comprendre votre problème, mais j'ai une configuration similaire dans laquelle j'utilise un menu déroulant de navigation. Voici ce qui fonctionne pour moi:

1.) Chargez le fragment à partir d'un fichier XML et appelez setupMapIfNeeded ()

SupportMapFragment mapFragment = (SupportMapFragment) getSupportFragmentManager()
                .findFragmentById(R.id.basicMap);

setUpMapIfNeeded();

Voici le fichier XML pour référence:

<?xml version="1.0" encoding="utf-8"?>
<fragment xmlns:Android="http://schemas.Android.com/apk/res/Android"
  Android:id="@+id/basicMap"
  Android:layout_width="match_parent"
  Android:layout_height="match_parent"
  class="com.google.Android.gms.maps.SupportMapFragment" />

2.) Ensuite, configurez la carte (pour plus de détails sur isGoogleMapsInstalled (), voir cette question )

    private void setUpMapIfNeeded() 
    {
    // Do a null check to confirm that we have not already instantiated the map.
    if (mMap == null) 
    {
        // Try to obtain the map from the SupportMapFragment.
        mMap = ((SupportMapFragment) getSupportFragmentManager().findFragmentById(R.id.basicMap)).getMap();
        // Check if we were successful in obtaining the map.
        if(isGoogleMapsInstalled())
        {
            if (mMap != null) 
            {
                mMap.setOnCameraChangeListener(getCameraChangeListener());
                mMap.setInfoWindowAdapter(new MyCustomInfoWindowAdapter(this));
            }
        }
        else
        {
            MapConstants.showDialogWithTextAndButton(this, R.string.installGoogleMaps, R.string.install, false, getGoogleMapsListener());
        }
    }
    }

3.) Assurez-vous d'appeler également setUpMapIfNeeded () à partir de onResume ():

public void onResume()
{
    super.onResume();

    setUpMapIfNeeded();
}
0
DiscDev