maintenant que le SDK final est sorti avec google apis - quelle est la meilleure façon de créer un fragment avec MapView? MapView a besoin d'une MapActivity pour fonctionner correctement.
Faire en sorte que l'activité gérant les fragments hérite de MapActivity (mauvaise solution car cela va à l'encontre de l'idée que les fragments sont autonomes) et utiliser une mise en page standard basée sur XML ne fonctionne pas. J'obtiens une NullPointerException dans MapActivity.setupMapView ():
E/AndroidRuntime (597): causée par: Java.lang.NullPointerException E/AndroidRuntime (597): à com.google.Android.maps.MapActivity.setupMapView (MapActivity.Java:400 ) E/AndroidRuntime (597): sur com.google.Android.maps.MapView. (MapView.Java:289) E/AndroidRuntime (597): sur com.google.Android. maps.MapView. (MapView.Java:264) E/AndroidRuntime (597): sur com.google.Android.maps.MapView. (MapView.Java:247)
Ma deuxième idée était de créer le MapView par programme et de transmettre l'activité associée (via getActivity ()) en tant que contexte au constructeur MapView. Ne marche pas:
E/AndroidRuntime (834): causée par: Java.lang.IllegalArgumentException: MapViews ne peut être créé qu'à l'intérieur d'instances de MapActivity. E/AndroidRuntime (834): sur com.google.Android. maps.MapView. (MapView.Java:291) E/AndroidRuntime (834): sur com.google.Android.maps.MapView. (MapView.Java:235) E/AndroidRuntime ( 834): sur de.foo.FinderMapFragment.onCreateView (FinderMapFragment.Java:225) E/AndroidRuntime (834): sur Android.app.FragmentManagerImpl.moveToState (FragmentManager.Java:708) E/AndroidRuntime (834): sur Android.app.FragmentManagerImpl.moveToState (FragmentManager.Java:900) E/AndroidRuntime (834): sur Android.app.FragmentManagerImpl.addFragment (FragmentManager.Java:978) E/AndroidRuntime (834): sur Android.app.Activity.onCreateView (Activity.Java:4090) E/AndroidRuntime (834): sur Android.view.LayoutInflater.createViewFromTag (LayoutInflater.Java : 664)
Vraiment, il devrait y avoir quelque chose comme MapFragment qui s'occupe des threads d'arrière-plan dont MapView a besoin, je suppose ... Alors, quelle est la meilleure pratique actuelle pour le faire?
Merci et salutations de l'Allemagne, Valentin
Depuis le 03.12.2012, Google a publié Google Maps Android API v2 . Vous pouvez maintenant oublier ces problèmes. - https://developers.google.com/maps/documentation/Android/
Exemple utilisant une nouvelle API - https://developers.google.com/maps/documentation/Android/start#add_a_map
Cette API fonctionnera pendant au moins Android API 8, alors utilisez-la;).
Alors maintenant, vous pouvez simplement utiliser la classe de fragments "com.google.Android.gms.maps.MapFragment". Il affichera la carte dans votre activité. Exemple de mise en page du lien ci-dessus:
<?xml version="1.0" encoding="utf-8"?>
<fragment xmlns:Android="http://schemas.Android.com/apk/res/Android"
Android:id="@+id/map"
Android:layout_width="match_parent"
Android:layout_height="match_parent"
class="com.google.Android.gms.maps.MapFragment"/>
J'ai réussi à résoudre ce problème en utilisant TabHost en fragment.
Voici l'idée (brièvement):
MainFragmentActivity
étend FragmentActivity
(depuis la bibliothèque de support) et a MapFragment
.
MyMapActivity
étend MapActivity
et contient MapView
.
LocalActivityManagerFragment
hôtes LocalActivityManager
MapFragment
étend LocalActivityManagerFragment
.
Et LocalActivityManager
contient une activité MyMapActivity
.
Exemple d'implémentation: https://github.com/inazaruk/map-fragment .
Comme indiqué sur Google Groups , Peter Doyle a également créé une bibliothèque de compatibilité personnalisée prenant en charge Google Maps. Android-support-v4-googlemaps
Cependant, il y a aussi un inconvénient:
Actuellement, un inconvénient est que TOUTES les classes étendant FragmentActivity sont MapActivitys. Il est possible de créer une classe distincte (c'est-à-dire FragmentMapActivity), mais cela nécessite une refactorisation du code FragmentActivity.
Juste pour clarifier la réponse. J'ai essayé l'approche suggérée par inazaruk et ChristophK. En fait, vous pouvez exécuter n'importe quelle activité dans un fragment - pas seulement Google Maps. Voici le code qui implémente l'activité google map en tant que fragment grâce à inazaruk et ChristophK.
import com.actionbarsherlock.app.SherlockFragment;
import Android.view.Window;
import Android.app.LocalActivityManager;
import Android.content.Intent;
import Android.os.Bundle;
import Android.view.LayoutInflater;
import Android.view.View;
import Android.view.ViewGroup;
public class MapFragment extends SherlockFragment {
private static final String KEY_STATE_BUNDLE = "localActivityManagerState";
private LocalActivityManager mLocalActivityManager;
protected LocalActivityManager getLocalActivityManager() {
return mLocalActivityManager;
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Bundle state = null;
if (savedInstanceState != null) {
state = savedInstanceState.getBundle(KEY_STATE_BUNDLE);
}
mLocalActivityManager = new LocalActivityManager(getActivity(), true);
mLocalActivityManager.dispatchCreate(state);
}
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
//This is where you specify you activity class
Intent i = new Intent(getActivity(), GMapActivity.class);
Window w = mLocalActivityManager.startActivity("tag", i);
View currentView=w.getDecorView();
currentView.setVisibility(View.VISIBLE);
currentView.setFocusableInTouchMode(true);
((ViewGroup) currentView).setDescendantFocusability(ViewGroup.FOCUS_AFTER_DESCENDANTS);
return currentView;
}
@Override
public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
outState.putBundle(KEY_STATE_BUNDLE,
mLocalActivityManager.saveInstanceState());
}
@Override
public void onResume() {
super.onResume();
mLocalActivityManager.dispatchResume();
}
@Override
public void onPause() {
super.onPause();
mLocalActivityManager.dispatchPause(getActivity().isFinishing());
}
@Override
public void onStop() {
super.onStop();
mLocalActivityManager.dispatchStop();
}
@Override
public void onDestroy() {
super.onDestroy();
mLocalActivityManager.dispatchDestroy(getActivity().isFinishing());
}
}
Bonnes nouvelles de Google à ce sujet. Ils publient aujourd'hui une nouvelle API Google Maps , avec des cartes d'intérieur et MapFragment.
With this new API, adding a map to your Activity is as simple as:
<fragment
Android:id="@+id/map"
Android:layout_width="match_parent"
Android:layout_height="match_parent"
class="com.google.Android.gms.maps.MapFragment" />
L'API Google Maps ne fait pas partie de l'AOSP. Tant qu'aucun Googler ne répond, il est à peine possible de dire s'il y aura un MapFragment à l'avenir.
Une alternative limitée possible consiste à utiliser un WebViewFragment
et à en abuser pour charger une URL maps.google.com
Personnalisée.
Voici une version MonoDroid (Mono pour Android) d'une version très simplifiée MapFragment:
public class MapFragment : Fragment
{
// FOLLOW http://stackoverflow.com/questions/5109336/mapview-in-a-fragment-honeycomb
private static String KEY_STATE_BUNDLE = "localActivityManagerState";
public override void OnCreate(Bundle savedInstanceState)
{
base.OnCreate(savedInstanceState);
Bundle state = null;
if (savedInstanceState != null) {
state = savedInstanceState.GetBundle(KEY_STATE_BUNDLE);
}
mLocalActivityManager = new LocalActivityManager(Activity, true);
mLocalActivityManager.DispatchCreate(state);
}
public override Android.Views.View OnCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
{
//This is where you specify you activity class
Intent i = new Intent(Activity, typeof(SteamLocationMapActivity));
Window w = mLocalActivityManager.StartActivity("tag", i);
View currentView=w.DecorView;
currentView.Visibility = ViewStates.Visible;
currentView.FocusableInTouchMode = true;
((ViewGroup) currentView).DescendantFocusability = DescendantFocusability.AfterDescendants;
return currentView;
}
private LocalActivityManager mLocalActivityManager;
protected LocalActivityManager GetLocalActivityManager() {
return mLocalActivityManager;
}
public override void OnSaveInstanceState(Bundle outState)
{
base.OnSaveInstanceState(outState);
outState.PutBundle(KEY_STATE_BUNDLE,mLocalActivityManager.SaveInstanceState());
}
public override void OnResume()
{
base.OnResume();
mLocalActivityManager.DispatchResume();
}
public override void OnPause()
{
base.OnPause();
mLocalActivityManager.DispatchPause(Activity.IsFinishing);
}
public override void OnStop()
{
base.OnStop();
mLocalActivityManager.DispatchStop();
}
}
Dommage que Google n'ait pas encore répondu. FWIW si vous avez vraiment besoin de faire cela, je n'ai pas trouvé d'autre moyen que:
Faites en sorte que l'onglet Gestion de l'activité hérite de MapActivity, créez le MapView dedans par programme, faites en sorte que mapfragment.xml contienne un ViewGroup et ajoutez le MapView au ViewGroup à l'aide de
((ViewGroup) getFragmentManager (). FindFragmentById (R.id.Finder_map_fragment) .getView ()) addView (mapView) ;;
Cela va clairement à l'encontre de l'idée que les fragments doivent être autonomes, mais ...
Puis-je obtenir la solution:
Cela résout mon problème en ajoutant MapView dans des fragments. https://github.com/petedoyle/Android-support-v4-googlemaps
Avec la nouvelle version d'ABS 4.0, il n'y a pas de support pour MapFragmentActivity, voici une bonne solution pour avoir une vue de carte dans un Fragment!
https://xrigau.wordpress.com/2012/03/22/howto-actionbarsherlock-mapfragment-listfragment/#comment-21
J'ai écrit une petite bibliothèque, écrasant les solutions basées sur LocalActivityManager au problème MapFragment (comprend également un exemple d'application montrant diverses situations d'utilisation):