web-dev-qa-db-fra.com

Comment utiliser Google Map V2 dans un fragment?

J'ai un fragment qui fait partie de Viewpager et je souhaite utiliser Google Map V2 à l'intérieur de ce fragment. C'est ce que j'ai essayé jusqu'à présent,

Dans mon fragment,

    private SupportMapFragment map;
      private GoogleMap mMapView;

   @Override
    public void onActivityCreated(Bundle savedInstanceState) {
        // TODO Auto-generated method stub
        super.onActivityCreated(savedInstanceState);

        FragmentManager fm = getChildFragmentManager();
        map = (SupportMapFragment) fm.findFragmentById(R.id.map);
        if (map == null) {
            map = SupportMapFragment.newInstance();
            fm.beginTransaction().replace(R.id.map, map).commit();
        }



    }

    @Override
    public void onResume() {
        super.onResume();
        if (mMapView == null) {
            mMapView = map.getMap();
            Marker hamburg = mMapView.addMarker(new MarkerOptions().position(HAMBURG)
                      .title("Hamburg"));
                  Marker kiel = mMapView.addMarker(new MarkerOptions()
                      .position(KIEL)
                      .title("Kiel")
                      .snippet("Kiel is cool")
                      .icon(BitmapDescriptorFactory
                          .fromResource(R.drawable.ic_launcher)));


                  mMapView.moveCamera(CameraUpdateFactory.newLatLngZoom(HAMBURG, 15));

                  // Zoom in, animating the camera.
           mMapView.animateCamera(CameraUpdateFactory.zoomTo(10), 2000, null);


        }
    }

et dans ma mise en page subfragment_info.xml, j'ai,

<fragment
            Android:id="@+id/map"
            class="com.google.Android.gms.maps.SupportMapFragment"
            Android:layout_width="match_parent"
            Android:layout_height="300dp"
            Android:layout_alignParentLeft="true"
            Android:layout_below="@+id/tableLayout1" />

Je peux voir la carte maintenant. Mais les marqueurs ne sont pas visibles. Je pense que ma carte Google mMapView est nulle. S'il vous plaît, aidez-moi à résoudre ce problème. Merci d'avance.

27
Basim Sherif

Créez un cadre pour la carte dans lequel il sera ajouté dans votre mise en page XML

<RelativeLayout
Android:layout_width="match_parent"
Android:layout_height="match_parent"
Android:id="@+id/map_container">

<!-- The map fragments will go here --> 
</RelativeLayout>

N'incluez pas class = "com.google.Android.gms.maps.SupportMapFragment" dans xml soit dans votre classe de fragment, récupérez-le manuellement dans onActivityCreated

    @Override
public void onActivityCreated(Bundle savedInstanceState) {
    super.onActivityCreated(savedInstanceState);
    FragmentManager fm = getChildFragmentManager();
    fragment = (SupportMapFragment) fm.findFragmentById(R.id.map_container);
    if (fragment == null) {
        fragment = SupportMapFragment.newInstance();
        fm.beginTransaction().replace(R.id.map_container, fragment).commit();
    }


/***at this time google play services are not initialize so get map and add what ever you want to it in onResume() or onStart() **/
}

@Override
    public void onResume() {
        super.onResume();
        if (map == null) {
            map = fragment.getMap();
            map.addMarker(new MarkerOptions().position(new LatLng(0, 0)));
        }
    }

si vous rencontrez des problèmes, il y a une exception d'état illégal. Écrivez simplement le code ci-dessous.

/ * * Ce problème est suivi dans (Google Bugs) * http://code.google.com/p/gmaps-api-issues/issues/detail?id=5064 Ajouté * Code dû à Une exception d'état illégal se produit lors d'un nouveau clic sur l'onglet * * Une solution à court terme qui l'a corrigé pour moi consiste à ajouter ce qui suit à * onDetach () de chaque fragment que vous appelez * /

@Override
    public void onDetach() {
        super.onDetach();

        try {
            Field childFragmentManager = Fragment.class
                    .getDeclaredField("mChildFragmentManager");
            childFragmentManager.setAccessible(true);
            childFragmentManager.set(this, null);

        } catch (NoSuchFieldException e) {
            throw new RuntimeException(e);
        } catch (IllegalAccessException e) {
            throw new RuntimeException(e);
        }
    }

// Si vous souhaitez afficher la carte en activité, étendez simplement votre activité par // FragmentActivity, écrivez la mention de code ci-dessous

Dans onCreate

FragmentManager fm = getSupportFragmentManager();
        fragment = (SupportMapFragment) fm.findFragmentById(R.id.map_container);
        if (fragment == null) {
            fragment = SupportMapFragment.newInstance();
            fm.beginTransaction().replace(R.id.map_container, fragment)
                    .commit();
    }

Dans onResume

@Override
    protected void onResume() {
        super.onResume();
        if (googleMap == null) {
            initilizeMap();

        }
    }

private void initilizeMap() {
        if (googleMap != null) {

            googleMap = fragment.getMap();
            googleMap.setMapType(GoogleMap.MAP_TYPE_NORMAL);
            googleMap.getUiSettings().setMyLocationButtonEnabled(true);
            googleMap.getUiSettings().setCompassEnabled(true);
            googleMap.getUiSettings().setRotateGesturesEnabled(true);

            CameraPosition cameraPosition = new CameraPosition.Builder()
                    .target(new LatLng(latitude, longitude)).zoom(10).build();
            googleMap.animateCamera(CameraUpdateFactory
                    .newCameraPosition(cameraPosition));

            // create marker
            MarkerOptions marker = new MarkerOptions().position(new LatLng(
                    latitude, longitude));
            // ROSE color icon
            marker.icon(BitmapDescriptorFactory
                    .defaultMarker(BitmapDescriptorFactory.HUE_ROSE));
            // adding marker
            googleMap.addMarker(marker);

            // check if map is created successfully or not
            if (googleMap == null) {
                Toast.makeText(getApplicationContext(),
                        "Sorry! unable to create maps", Toast.LENGTH_SHORT)
                        .show();
            }
        }
    }

Une aide supplémentaire peut être obtenue à partir de ces liens
https://code.google.com/p/gmaps-api-issues/issues/detail?id=5064#c1https://developers.google .com/maps/documentation/Android/map

50
DeepakPanwar

Vous devez décider si vous créez votre fragment dans le code new SupportMapFragment() ou gonflez à partir de xml class="com.google.Android.gms.maps.SupportMapFragment".

En fait, vous ne pouvez pas avoir un Fragment en xml pour un autre Fragment. En savoir plus sur imbriqué Fragments .

Vous pouvez suivre ce commentaire sur la façon d'ajouter des SupportMapFragment imbriqués.

12
MaciejGórski

J'ai eu plus ou moins le même problème. J'avais un tiroir de navigation et je voulais mettre la carte en fragments.

J'ai suivi ce fil (mais il est en espagnol): https://groups.google.com/forum/#!msg/desarrolladores-Android/1cvqPm0EZZU/Q801Yvb2ntYJ

L'indice était (à mon avis) de changer le fichier layout.xml: Au lieu d'un "fragment" à l'intérieur de votre "layout subfragment_info.xml", vous devriez changer ceci:

<com.google.Android.gms.maps.MapView xmlns:Android="http://schemas.Android.com/apk/res/Android"
Android:id="@+id/map"
Android:layout_width="match_parent"
Android:layout_height="match_parent" />`

Voici le code à l'intérieur du fil (vous pouvez l'utiliser et l'adapter): https://groups.google.com/d/msg/desarrolladores-Android/1cvqPm0EZZU/9srw_9feamUJ

7
Ignacio Rubio

Pour charger la carte dans un fragment:

<fragment
    Android:id="@+id/fragmentMap1"
    Android:layout_width="match_parent"
    Android:layout_height="match_parent"
    class="com.google.Android.gms.maps.SupportMapFragment"/>

Pour .Java:

public class PathFragment extends Fragment {
    View view;
    GoogleMap mMap;
    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        view=inflater.inflate(R.layout.fragment_path,null);
         setupMap();
        return view;
    }

    private void setupMap()
    {
        if (mMap == null)
        {
            mMap = ((SupportMapFragment) getChildFragmentManager().findFragmentById(R.id.fragment_map1)).getMap();
            mMap.getUiSettings().setZoomControlsEnabled(true);
        }

        mMap.setOnMapLoadedCallback(new GoogleMap.OnMapLoadedCallback() {
            @Override
            public void onMapLoaded() {
                getlocation();
            }
        });
    }

    public void getlocation()
    {
        try
        {
            /*Collect Source and destination latitude and longitude
            * To draw Polyline
            * */

            LatLng src = new LatLng(Double.parseDouble(AppGlobal.WorkerHistory.getOrder_lat()),Double.parseDouble(AppGlobal.WorkerHistory.getOrder_lng()));
            LatLng dest =new LatLng(Double.parseDouble(AppGlobal.WorkerHistory.getWorker_lat()),Double.parseDouble(AppGlobal.WorkerHistory.getWorker_lng()));

            //Add Marker
            mMap.addMarker(new MarkerOptions()
                .position(src)
                .title("Source")
                .icon(BitmapDescriptorFactory.fromResource(R.drawable.srcicon)));


            mMap.addMarker(new MarkerOptions()
                .position(dest)
                .title("Destination")
                .icon(BitmapDescriptorFactory.fromResource(R.drawable.desticon)));



            Polyline line = mMap.addPolyline(
                new PolylineOptions().add(
                    new LatLng(src.latitude, src.longitude),
                    new LatLng(dest.latitude, dest.longitude)
                ).width(5).color(Color.RED).geodesic(true)
            );

            //set zoom level
            LatLngBounds.Builder builder = new LatLngBounds.Builder();
            builder.include(src);
            builder.include(dest);
            LatLngBounds bounds = builder.build();

            int padding = 0; // offset from edges of the map in pixels
            CameraUpdate cu = CameraUpdateFactory.newLatLngBounds(bounds, padding);
            mMap.animateCamera(cu);
        }
        catch (Exception e)
        {
            e.printStackTrace();
        }
    }
}
1
Arpita Acharya

En lien, répondez pour vous:

"Le problème est que ce que vous essayez de faire ne doit pas être fait. Vous ne devez pas gonfler des fragments à l'intérieur d'autres fragments. D'après la documentation d'Android:

Remarque: Vous ne pouvez pas gonfler une disposition en un fragment lorsque cette disposition comprend un. Les fragments imbriqués ne sont pris en charge que lorsqu'ils sont ajoutés à un fragment de manière dynamique.

Bien que vous puissiez être en mesure d'accomplir la tâche avec les hacks présentés ici, je vous suggère fortement de ne pas le faire. Il est impossible d'être sûr que ces hacks géreront ce que chaque nouveau système d'exploitation Android OS fait lorsque vous essayez de gonfler la disposition d'un fragment contenant un autre fragment.

La seule façon prise en charge par Android pour ajouter un fragment à un autre fragment est via une transaction à partir du gestionnaire de fragments enfants. "

Pour ce problème:

ID en double, étiquette nulle ou ID parent avec un autre fragment pour com.google.Android.gms.maps.MapFragment

Pour moi, la meilleure solution est de @DeepakPanwar

1
Cícero Moura

Pour MapFragment

 <fragment
    Android:id="@+id/map"
    Android:name="com.google.Android.gms.maps.MapFragment"
    Android:layout_width="match_parent"
    Android:layout_height="match_parent" />

Dans votre classe de fragments

map = ((MapFragment) getActivity().getFragmentManager()
            .findFragmentById(R.id.map)).getMap();
    map.addMarker(new MarkerOptions().position(
            new LatLng(13.031902, 80.278823)).title("Marker Title"));

Pour SupportMapFragment

<fragment
    Android:id="@+id/map"
    Android:name="com.google.Android.gms.maps.SupportMapFragment"
    Android:layout_width="match_parent"
    Android:layout_height="match_parent" />

Dans votre classe de fragments

map = ((SupportMapFragment) getActivity().getSupportFragmentManager()
            .findFragmentById(R.id.map)).getMap();
    map.addMarker(new MarkerOptions().position(
            new LatLng(13.031902, 80.278823)).title("Marker Title"));

Remarque - Le rendu de la carte SupportMapFragment une fois que l'utilisateur a touché la carte

1
Rajeshwar

mon approche est:

Bundle bundle = new Bundle();
bundle.putInt(MY_ID, id);

FragmentManager fm  = getFragmentManager();
Fragment fragment = fm.findFragmentById(R.id.customer_details_fragment);

fragment = new SalesFragment();
fm.beginTransaction()
  .add(R.id.customer_details_fragment, fragment)
  .commit();

fragment.setArguments(bundle);  
1
bofredo

C'est comme ça que je l'ai fait

dans la mise en page:

<fragment 
    Android:id="@+id/map"
      Android:layout_width="match_parent"
      Android:layout_height="match_parent"
      Android:layout_weight=".90"
      class="com.google.Android.gms.maps.SupportMapFragment"
      />

dans du code:

public class GPS extends FragmentActivity {

@Override
protected void onResume() {
    super.onResume();
    setUpMapIfNeeded();
}

private void setUpMapIfNeeded() {
    // Do a null check to confirm that we have not already instantiated the map.
    if (supportMap == null) {
        // Try to obtain the map from the SupportMapFragment.
        supportMap = ((SupportMapFragment) getSupportFragmentManager().findFragmentById(R.id.map))
                .getMap();
        // Check if we were successful in obtaining the map.
        if (supportMap != null) {
            MarkerOptions mo = new MarkerOptions().position( new LatLng( latitude, longitude ) );
            supportMap.addMarker( mo );
        }
    }
}
}

Ça m'a pris beaucoup de temps, vous avez besoin de la bonne combinaison de choses, assurez-vous que votre classe étend FragmentActivity

0
Patrick

Si je remplace le fragment, où se trouve le fragment de carte (dans cet exemple de code MyFragment) par un autre fragment, puis que je reviens, j'obtiens une exception IllegalStateException

public class Home_Map extends Fragment {

GoogleMap googleMap;
FragmentManager myFragmentManager;
SupportMapFragment mySupportMapFragment;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
        Bundle savedInstanceState) {
    // TODO Auto-generated method stub
     View rootView = inflater.inflate(R.layout.fragment_home__map, container, false);

     //googleMap.setMyLocationEnabled(true);

        try {
            // Loading map
            initilizeMap();
            googleMap.setMyLocationEnabled(true);

        } catch (Exception e) {
            e.printStackTrace();
        }
    return rootView;
}
 private void initilizeMap() {

        try
        {
        if (googleMap == null) {
            myFragmentManager = getFragmentManager();
            mySupportMapFragment = (SupportMapFragment)myFragmentManager.findFragmentById(R.id.map2);
            googleMap = mySupportMapFragment.getMap();

            if (googleMap == null) {
                Toast.makeText(getActivity().getApplicationContext(),
                        "Sorry! unable to create maps", Toast.LENGTH_SHORT)
                        .show();
            }
        }
        } catch (Exception e) { Toast.makeText(getActivity().getApplicationContext(), ""+e, 1).show();
            // TODO: handle exception
        }
    }

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

        initilizeMap();

    }

   @Override
    public void onDetach() {
        // TODO Auto-generated method stub
        super.onDetach();
          try {
                Field childFragmentManager = Fragment.class
                        .getDeclaredField("mChildFragmentManager");
                childFragmentManager.setAccessible(true);
                childFragmentManager.set(this, null);

            } catch (NoSuchFieldException e) {
                throw new RuntimeException(e);
            } catch (IllegalAccessException e) {
                throw new RuntimeException(e);
            }
    }

    }
0
Suraj Singh