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.
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
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é Fragment
s .
Vous pouvez suivre ce commentaire sur la façon d'ajouter des SupportMapFragment
imbriqués.
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
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();
}
}
}
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:
Pour moi, la meilleure solution est de @DeepakPanwar
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
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);
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
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);
}
}
}