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?
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.
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" />
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();
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);
}
}
});
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" />
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);
}
}
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" />
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
.
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;
}
}
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);
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;
}
}
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!