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?
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é.
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
.
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, dansonViewCreated
Mé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()
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();
}