MapView dans un Fragment (nid D'abeille))

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 Mapactivité pour fonctionner correctement.

avoir l'activité Gérer les Fragments hériter de MapActivity (mauvaise solution car elle va à l'encontre de l'idée que les Fragments sont autonomes) et utiliser une mise en page xml régulière ne fonctionne pas. Je reçois une NullPointerException dans MapActivity.setupMapView ():

E/AndroidRuntime(  597): Caused by: java.lang.NullPointerException
E/AndroidRuntime(  597):    at com.google.android.maps.MapActivity.setupMapView(MapActivity.java:400)
E/AndroidRuntime(  597):    at com.google.android.maps.MapView.(MapView.java:289)
E/AndroidRuntime(  597):    at com.google.android.maps.MapView.(MapView.java:264)
E/AndroidRuntime(  597):    at com.google.android.maps.MapView.(MapView.java:247)

My la deuxième idée était de créer le MapView de manière programmatique et de passer l'activité associée (via getActivity()) comme contexte au constructeur MapView. Ne fonctionne pas:

E/AndroidRuntime(  834): Caused by: java.lang.IllegalArgumentException: MapViews can only be created inside instances of MapActivity.
E/AndroidRuntime(  834):    at com.google.android.maps.MapView.(MapView.java:291)
E/AndroidRuntime(  834):    at com.google.android.maps.MapView.(MapView.java:235)
E/AndroidRuntime(  834):    at de.foo.FinderMapFragment.onCreateView(FinderMapFragment.java:225)
E/AndroidRuntime(  834):    at android.app.FragmentManagerImpl.moveToState(FragmentManager.java:708)
E/AndroidRuntime(  834):    at android.app.FragmentManagerImpl.moveToState(FragmentManager.java:900)
E/AndroidRuntime(  834):    at android.app.FragmentManagerImpl.addFragment(FragmentManager.java:978)
E/AndroidRuntime(  834):    at android.app.Activity.onCreateView(Activity.java:4090)
E/AndroidRuntime(  834):    at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:664)

vraiment il devrait y avoir quelque chose comme MapFragment qui prend soin des fils de fond dont MapView a besoin je suppose... Quelle est donc la meilleure pratique actuelle pour ce faire?

remerciements et salutations de L'Allemagne, Valentin 151930920"

81
demandé sur Programmer Bruce 2011-02-24 22:15:30

12 réponses

en date du 03.12.2012 Google a publié Google Maps API Android v2 . Maintenant, vous pouvez oublier ces problèmes. https://developers.google.com/maps/documentation/android /

exemple utilisant la nouvelle API - https://developers.google.com/maps/documentation/android/start#add_a_map

cette API fonctionnera pour au moins Android API 8, donc utilisez-le ;).

alors maintenant vous pouvez simplement utiliser "com.Google.Android.gms.cartographie.MapFragment" fragment de la classe. Il affiche la carte dans votre Activité. Exemple de Layout à partir 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"/>
8
répondu Paul Annekov 2012-12-11 15:18:09

j'ai réussi à résoudre ce problème en utilisant TabHost dans fragment.

Voici l'idée (brièvement):

  1. MainFragmentActivity étend FragmentActivity (de la bibliothèque de soutien) et a MapFragment .

  2. MyMapActivity s'étend MapActivity et contiennent MapView .

  3. "151960920 hôtes" LocalActivityManager

  4. MapFragment s'étend LocalActivityManagerFragment .

  5. Et LocalActivityManager contient MyMapActivity de l'activité.

exemple de mise en œuvre: https://github.com/inazaruk/map-fragment .


enter image description here

87
répondu inazaruk 2012-08-25 18:38:24

comme indiqué sur Google Groups , Peter Doyle a construit une bibliothèque de compatibilité personnalisée supportant aussi Google Maps. android-support-v4-googlemaps

cependant, il y a un inconvénient aussi:

actuellement, un inconvénient est que toutes les classes étendant L'activité de fragmentation sont des MapActivitys. Il est possible de faire une classe séparée (i.e. FragmentMapActivity), mais cela nécessite un certain remaniement de le code de Fragmentactivité.

23
répondu TomTasche 2011-07-28 11:36:26

Juste pour clarifier la réponse. J'ai essayé l'approche suggérée par inazaruk et Christophe. 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 comme un fragment grâce à inazaruk et Christophe.

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());
    }
}
13
répondu zmicer 2012-05-24 14:11:56

grande nouvelle de Google à ce sujet. Ils sortent aujourd'hui un nouvelle API Google Maps , avec des cartes intérieures 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" />
4
répondu Marcelo 2012-12-03 19:48:14

L'API GoogleMaps 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 dans le futur.

une alternative limitée possible est d'utiliser une WebViewFragment et d'en abuser pour charger une URL personnalisée maps.google.com .

2
répondu Octavian Damiean 2011-02-24 19:26:20

HM 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:

avoir L'onglet Gérer L'activité hériter de MapActivity, créer le MapView dans là programmatically, avoir le mapfragment.xml contiennent un ViewGroup et ajouter la MapView à la 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 ...

2
répondu Valentin 2011-02-25 17:25:50

Voici une version MonoDroid ( Mono for Android ) d'une version très simplifiée MapFragment :

public class MapFragment : Fragment
{
    // FOLLOW /q/mapview-in-a-fragment-honeycomb-74111/"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();
    }
}
2
répondu BahaiResearch.com 2012-10-02 02:15:01

cela résout mon problème en ajoutant MapView en Fragments. https://github.com/petedoyle/android-support-v4-googlemaps

1
répondu Sudhin Philip 2012-03-11 09:42:07

avec la nouvelle version D'ABS 4.0, il n'y a pas de support pour MapFragmentActivity, voici une bonne solution pour avoir un mapview dans un Fragment!

https://xrigau.wordpress.com/2012/03/22/howto-actionbarsherlock-mapfragment-listfragment/#comment-21

1
répondu cesards 2012-04-04 07:08:31

Peut-on avoir la solution:

  1. créer une classe TempFragmentActivity extends MapActivity
  2. il y a un objet MapView à L'intérieur de TempFragmentActivity(comme normal define en xml)
  3. supprimer cette forme d'objet MapView parent (LinearLayout) (supprimer l'exception ultérieure)
  4. garder cet objet MapView quelque part (ex: membre statique de TempFragmentActivity)
  5. dans votre Fragment , ajouter cet objet MapView utilisant le code (ne pas définir en xml) dans un certain Liner-Layout
1
répondu Joe Zhang 2012-05-10 14:18:14

j'ai écrit une petite bibliothèque, écrasant le LocalActivityManager de solutions basées sur la MapFragment problème (comprend également un exemple d'application montrant les différentes situations d'utilisation):

https://github.com/coreform/android-tandemactivities

0
répondu straya 2012-08-29 00:08:20