web-dev-qa-db-fra.com

Comment mettre Google Maps V2 sur un fragment à l'aide de ViewPager

J'essaie de faire une mise en page même dans le Play Store. J'ai eu à afficher la mise en page onglet en utilisant un fragment et viewpager de androidhive. Cependant, je ne peux pas implémenter google maps v2 dessus. J'ai déjà effectué des recherches sur Internet pendant des heures, mais je ne trouve pas de didacticiel sur la procédure à suivre. Quelqu'un peut-il me montrer comment?

123
Jeongbebs

En utilisant ce code, nous pouvons configurer MapView n'importe où, dans n'importe quel ViewPager, fragment ou activité.

Dans la dernière mise à jour de Google for Maps, seul MapView est pris en charge pour les fragments. MapFragment & SupportMapFragment ne fonctionne pas. Je me trompe peut-être, mais c'est ce que j'ai constaté après avoir tenté d'implémenter MapFragment & SupportMapFragment.

Configuration de la présentation pour afficher la carte dans le fichier location_fragment.xml:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:Android="http://schemas.Android.com/apk/res/Android"
    Android:layout_width="match_parent"
    Android:layout_height="match_parent" >

    <com.google.Android.gms.maps.MapView
        Android:id="@+id/mapView"
        Android:layout_width="match_parent"
        Android:layout_height="match_parent" />

</RelativeLayout>

Nous codons maintenant la classe Java pour afficher la carte dans le fichier MapViewFragment.Java:

public class MapViewFragment extends Fragment {

    MapView mMapView;
    private GoogleMap googleMap;

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        View rootView = inflater.inflate(R.layout.location_fragment, container, false);

        mMapView = (MapView) rootView.findViewById(R.id.mapView);
        mMapView.onCreate(savedInstanceState);

        mMapView.onResume(); // needed to get the map to display immediately

        try {
            MapsInitializer.initialize(getActivity().getApplicationContext());
        } catch (Exception e) {
            e.printStackTrace();
        }

        mMapView.getMapAsync(new OnMapReadyCallback() {
            @Override
            public void onMapReady(GoogleMap mMap) {
                googleMap = mMap;

                // For showing a move to my location button
                googleMap.setMyLocationEnabled(true);

                // For dropping a marker at a point on the Map
                LatLng sydney = new LatLng(-34, 151);
                googleMap.addMarker(new MarkerOptions().position(sydney).title("Marker Title").snippet("Marker Description"));

                // For zooming automatically to the location of the marker
                CameraPosition cameraPosition = new CameraPosition.Builder().target(sydney).zoom(12).build();
                googleMap.animateCamera(CameraUpdateFactory.newCameraPosition(cameraPosition));
            }
        });

        return rootView;
    }

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

    @Override
    public void onPause() {
        super.onPause();
        mMapView.onPause();
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        mMapView.onDestroy();
    }

    @Override
    public void onLowMemory() {
        super.onLowMemory();
        mMapView.onLowMemory();
    }
}

Pour terminer, vous devez obtenir la clé API de votre application en l'enregistrant sur Console Google Cloud . Enregistrez votre application en tant qu'application Android native.

274
arshu

L'approche suivante fonctionne pour moi.

import Android.os.Bundle;
import Android.support.v4.app.Fragment;
import Android.view.LayoutInflater;
import Android.view.View;
import Android.view.ViewGroup;

import com.google.Android.gms.maps.CameraUpdateFactory;
import com.google.Android.gms.maps.GoogleMap;
import com.google.Android.gms.maps.MapView;
import com.google.Android.gms.maps.MapsInitializer;
import com.google.Android.gms.maps.model.BitmapDescriptorFactory;
import com.google.Android.gms.maps.model.CameraPosition;
import com.google.Android.gms.maps.model.LatLng;
import com.google.Android.gms.maps.model.MarkerOptions;

/**
 * A fragment that launches other parts of the demo application.
 */
public class MapFragment extends Fragment {

MapView mMapView;
private GoogleMap googleMap;

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
        Bundle savedInstanceState) {
    // inflat and return the layout
    View v = inflater.inflate(R.layout.fragment_location_info, container,
            false);
    mMapView = (MapView) v.findViewById(R.id.mapView);
    mMapView.onCreate(savedInstanceState);

    mMapView.onResume();// needed to get the map to display immediately

    try {
        MapsInitializer.initialize(getActivity().getApplicationContext());
    } catch (Exception e) {
        e.printStackTrace();
    }

    googleMap = mMapView.getMap();
    // latitude and longitude
    double latitude = 17.385044;
    double longitude = 78.486671;

    // create marker
    MarkerOptions marker = new MarkerOptions().position(
            new LatLng(latitude, longitude)).title("Hello Maps");

    // Changing marker icon
    marker.icon(BitmapDescriptorFactory
            .defaultMarker(BitmapDescriptorFactory.HUE_ROSE));

    // adding marker
    googleMap.addMarker(marker);
    CameraPosition cameraPosition = new CameraPosition.Builder()
            .target(new LatLng(17.385044, 78.486671)).zoom(12).build();
    googleMap.animateCamera(CameraUpdateFactory
            .newCameraPosition(cameraPosition));

    // Perform any camera updates here
    return v;
}

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

@Override
public void onPause() {
    super.onPause();
    mMapView.onPause();
}

@Override
public void onDestroy() {
    super.onDestroy();
    mMapView.onDestroy();
}

@Override
public void onLowMemory() {
    super.onLowMemory();
    mMapView.onLowMemory();
}
}

fragment_location_info.xml

<?xml version="1.0" encoding="utf-8"?>
<com.google.Android.gms.maps.MapView
xmlns:Android="http://schemas.Android.com/apk/res/Android"
Android:id="@+id/mapView"
Android:layout_width="match_parent"
Android:layout_height="match_parent" />
140
Brandon Yang

Vous pouvez utiliser cette ligne si vous souhaitez utiliser GoogleMap dans un fragment:

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

GoogleMap mGoogleMap = ((SupportMapFragment) getChildFragmentManager().findFragmentById(R.id.map)).getMap();
76
Maddy

Dernières informations avec getMapAsync au lieu de celui qui est obsolète.

1. vérifier le manifeste pour  

<meta-data Android:name="com.google.Android.geo.API_KEY" Android:value="xxxxxxxxxxxxxxxxxxxxxxxxx"/>

Vous pouvez obtenir la clé API de votre application en l'enregistrant à Google Cloud Console. Enregistrez votre application en tant qu'application Android native 

2. dans votre structure de fragment .xml add FrameLayout (pas fragment):

                  <FrameLayout
                Android:layout_width="match_parent"
                Android:layout_height="250dp"
                Android:layout_weight="2"
                Android:name="com.google.Android.gms.maps.SupportMapFragment"
                Android:id="@+id/mapwhere" />

ou quelle que soit votre taille

3. Dans onCreateView dans votre fragment

    private SupportMapFragment mSupportMapFragment; 

    mSupportMapFragment = (SupportMapFragment) getChildFragmentManager().findFragmentById(R.id.mapwhere);
    if (mSupportMapFragment == null) {
        FragmentManager fragmentManager = getFragmentManager();
        FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
        mSupportMapFragment = SupportMapFragment.newInstance();
        fragmentTransaction.replace(R.id.mapwhere, mSupportMapFragment).commit();
    }

    if (mSupportMapFragment != null)
    {
        mSupportMapFragment.getMapAsync(new OnMapReadyCallback() {
            @Override public void onMapReady(GoogleMap googleMap) {
                if (googleMap != null) {

                    googleMap.getUiSettings().setAllGesturesEnabled(true);

                      -> marker_latlng // MAKE THIS WHATEVER YOU WANT

                        CameraPosition cameraPosition = new CameraPosition.Builder().target(marker_latlng).zoom(15.0f).build();
                        CameraUpdate cameraUpdate = CameraUpdateFactory.newCameraPosition(cameraPosition);
                        googleMap.moveCamera(cameraUpdate);

                }

            }
        });
48
OWADVL

voici ce que j'ai fait en détail:

À partir de là, vous pouvez obtenir la clé de l'API Google Map

manière alternative et simple

connectez-vous d'abord à votre compte google et visitez les bibliothèques google et sélectionnez Google Maps Android API

dépendance trouvée dans l'activité de carte par défaut du studio Android:

compile 'com.google.Android.gms:play-services:10.0.1'

mettre votre clé dans le fichier Mainifest Android sous application comme ci-dessous

dans AndroidMainifest.xml, effectuez les modifications suivantes:

    // required permission
    <uses-permission Android:name="Android.permission.ACCESS_FINE_LOCATION" />


        // google map api key put under/inside <application></application>
        // Android:value="YOUR API KEY"
        <meta-data
            Android:name="com.google.Android.geo.API_KEY"
            Android:value="AIzasdfasdf645asd4f847sad5f45asdf7845" />

Code de fragment:

public class MainBranchFragment extends Fragment implements OnMapReadyCallback{

private GoogleMap mMap;
    public MainBranchFragment() {
        // Required empty public constructor
    }


    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        // Inflate the layout for this fragment
        View view= inflater.inflate(R.layout.fragment_main_branch, container, false);
        SupportMapFragment mapFragment = (SupportMapFragment) getChildFragmentManager().findFragmentById(R.id.main_branch_map);
        mapFragment.getMapAsync(this);
        return view;
    }




     @Override
        public void onMapReady(GoogleMap googleMap) {
            mMap = googleMap;
            LatLng UCA = new LatLng(-34, 151);
            mMap.addMarker(new MarkerOptions().position(UCA).title("YOUR TITLE")).showInfoWindow();

            mMap.animateCamera(CameraUpdateFactory.newLatLngZoom(UCA,17));

        }
    }

en vous fragmentez xml:

<fragment
                Android:id="@+id/main_branch_map"
                Android:name="com.google.Android.gms.maps.SupportMapFragment"
                Android:layout_width="match_parent"
                Android:layout_height="match_parent"
                tools:context="com.googlemap.googlemap.MapsActivity" />
9
dharmx

Pour la question d'obtenir une NullPointerException lorsque nous changeons les onglets dans une FragmentTabHost, il vous suffit d'ajouter ce code à votre classe qui a la TabHost. Je veux dire la classe où vous initialisez les onglets. C'est le code:

/**** Fix for error : Activity has been destroyed, when using Nested tabs 
 * We are actually detaching this tab fragment from the `ChildFragmentManager`
 * so that when this inner tab is viewed back then the fragment is attached again****/

import Java.lang.reflect.Field;

@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);
    }
}
5
arshu
public class DemoFragment extends Fragment {


MapView mapView;
GoogleMap map;
LatLng CENTER = null;

public LocationManager locationManager;

double longitudeDouble;
double latitudeDouble;

String snippet;
String title;
Location location;
String myAddress;

String LocationId;
String CityName;
String imageURL;

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
        Bundle savedInstanceState) {
    // TODO Auto-generated method stub
    View view = inflater
                .inflate(R.layout.fragment_layout, container, false);

    mapView = (MapView) view.findViewById(R.id.mapView);
        mapView.onCreate(savedInstanceState);

  setMapView();


 }

 private void setMapView() {
    try {
        MapsInitializer.initialize(getActivity());

        switch (GooglePlayServicesUtil
                .isGooglePlayServicesAvailable(getActivity())) {
        case ConnectionResult.SUCCESS:
            // Toast.makeText(getActivity(), "SUCCESS", Toast.LENGTH_SHORT)
            // .show();

            // Gets to GoogleMap from the MapView and does initialization
            // stuff
            if (mapView != null) {

                locationManager = ((LocationManager) getActivity()
                        .getSystemService(Context.LOCATION_SERVICE));

                Boolean localBoolean = Boolean.valueOf(locationManager
                        .isProviderEnabled("network"));

                if (localBoolean.booleanValue()) {

                    CENTER = new LatLng(latitude, longitude);

                } else {

                }
                map = mapView.getMap();
                if (map == null) {

                    Log.d("", "Map Fragment Not Found or no Map in it!!");

                }

                map.clear();
                try {
                    map.addMarker(new MarkerOptions().position(CENTER)
                            .title(CityName).snippet(""));
                } catch (Exception e) {
                    e.printStackTrace();
                }

                map.setIndoorEnabled(true);
                map.setMyLocationEnabled(true);
                map.moveCamera(CameraUpdateFactory.zoomTo(5));
                if (CENTER != null) {
                    map.animateCamera(
                            CameraUpdateFactory.newLatLng(CENTER), 1750,
                            null);
                }
                // add circle
                CircleOptions circle = new CircleOptions();
                circle.center(CENTER).fillColor(Color.BLUE).radius(10);
                map.addCircle(circle);
                map.setMapType(GoogleMap.MAP_TYPE_NORMAL);

            }
            break;
        case ConnectionResult.SERVICE_MISSING:

            break;
        case ConnectionResult.SERVICE_VERSION_UPDATE_REQUIRED:

            break;
        default:

        }
    } catch (Exception e) {

    }

}

dans fragment_layout

<com.google.Android.gms.maps.MapView
                Android:id="@+id/mapView"
                Android:layout_width="match_parent"
                Android:layout_height="160dp"                    
                Android:layout_marginRight="10dp" />
4
Vaishali Sutariya

Lorsque vous ajoutez votre utilisation de la carte:

getChildFragmentManager().beginTransaction()
    .replace(R.id.menu_map_container, mapFragment, "f" + shabbatIndex).commit();

au lieu de .add et au lieu de getFragmentManager.

3
user1396018

je viens de créer MapActivity et de le gonfler en fragment . MapActivity.Java:

package com.example.ahmedsamra.mansouratourguideapp;

import Android.support.v4.app.FragmentActivity;
import Android.os.Bundle;

import com.google.Android.gms.maps.CameraUpdateFactory;
import com.google.Android.gms.maps.GoogleMap;
import com.google.Android.gms.maps.OnMapReadyCallback;
import com.google.Android.gms.maps.SupportMapFragment;
import com.google.Android.gms.maps.model.LatLng;
import com.google.Android.gms.maps.model.MarkerOptions;

public class MapsActivity extends FragmentActivity implements OnMapReadyCallback {

    private GoogleMap mMap;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_categories);//layout for container
        getSupportFragmentManager().beginTransaction()
                .replace(R.id.container, new MapFragment())
                .commit();
        // Obtain the SupportMapFragment and get notified when the map is ready to be used.
        SupportMapFragment mapFragment = (SupportMapFragment) getSupportFragmentManager()
                .findFragmentById(R.id.map);
        mapFragment.getMapAsync(this);
    }


    /**
     * Manipulates the map once available.
     * This callback is triggered when the map is ready to be used.
     * This is where we can add markers or lines, add listeners or move the camera. In this case,
     * we just add a marker near Sydney, Australia.
     * If Google Play services is not installed on the device, the user will be prompted to install
     * it inside the SupportMapFragment. This method will only be triggered once the user has
     * installed Google Play services and returned to the app.
     */
    @Override
    public void onMapReady(GoogleMap googleMap) {
        mMap = googleMap;

        // Add a marker in Sydney and move the camera
        LatLng mansoura = new LatLng(31.037933, 31.381523);
        mMap.addMarker(new MarkerOptions().position(mansoura).title("Marker in mansoura"));
        mMap.moveCamera(CameraUpdateFactory.newLatLng(mansoura));
    }
}

activity_map.xml:

<fragment xmlns:Android="http://schemas.Android.com/apk/res/Android"
    xmlns:map="http://schemas.Android.com/apk/res-auto"
    xmlns:tools="http://schemas.Android.com/tools"
    Android:id="@+id/map"
    Android:name="com.google.Android.gms.maps.SupportMapFragment"
    Android:layout_width="match_parent"
    Android:layout_height="match_parent"
    tools:context="com.example.ahmedsamra.mansouratourguideapp.MapsActivity" />

MapFragment.Java:-

package com.example.ahmedsamra.mansouratourguideapp;


import Android.os.Bundle;
import Android.support.v4.app.Fragment;
import Android.view.LayoutInflater;
import Android.view.View;
import Android.view.ViewGroup;
import Android.widget.TextView;

/**
 * A simple {@link Fragment} subclass.
 */
public class MapFragment extends Fragment {


    public MapFragment() {
        // Required empty public constructor
    }


    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        View rootView = inflater.inflate(R.layout.activity_maps,container,false);
        return rootView;
    }

}
1
ahmed samra

Ajout dynamique d'un fragment de carte pour afficher le pageur:

Si vous ciblez une application antérieure au niveau 12 de l'API, créez une instance de SupportedMapFragment et ajoutez-la à votre adaptateur de page d'affichage. 

SupportMapFragment supportMapFragment=SupportMapFragment.newInstance();
        supportMapFragment.getMapAsync(this);

API de niveau 12 ou supérieur prenant en charge les objets MapFragment

MapFragment mMapFragment=MapFragment.newInstance();
            mMapFragment.getMapAsync(this);
0
Adeeb karim

J'ai une solution de contournement pour NullPointerException lorsque je supprime un fragment de DestoryView, il suffit de mettre votre code dans onStop() pas onDestoryView. Ça fonctionne bien!

@Override
public void onStop() {
    super.onStop();
    if (mMap != null) {
        MainActivity.fragmentManager.beginTransaction()
                .remove(MainActivity.fragmentManager.findFragmentById(R.id.location_map)).commit();
        mMap = null;
    }
}
0

Selon https://developer.Android.com/about/versions/Android-4.2.html#NestedFragments , vous pouvez utiliser nested fragments pour cela en appelant getChildFragmentManager () if vous souhaitez toujours utiliser le fragment Google Maps au lieu de la vue à l'intérieur de votre propre fragment:

SupportMapFragment mapFragment = new SupportMapFragment();
FragmentTransaction transaction = getChildFragmentManager().beginTransaction();
transaction.add(R.id.content, mapFragment).commit();

où "contenu" est la mise en page racine de votre fragment (de préférence un FrameLayout). L'avantage d'utiliser un fragment de carte est que le cycle de vie de la carte est alors géré automatiquement par le système. 

Bien que la documentation indique "Vous ne pouvez pas gonfler une mise en page dans un fragment lorsque cette mise en page inclut un <fragment>. Les fragments imbriqués ne sont pris en charge que s'ils sont ajoutés à un fragment de manière dynamique", mais j'ai réussi à le faire et cela a bien fonctionné. Voici mon code: 
Dans la méthode onCreateView () du fragment:

View view = inflater.inflate(R.layout.layout_maps, container, false);
SupportMapFragment mapFragment = (SupportMapFragment) getChildFragmentManager().findFragmentById(R.id.map);
mapFragment.getMapAsync(...);

Dans la mise en page: 

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

J'espère que ça aide! 

0
Shreck Ye