J'ai besoin de votre aide ... Je travaille dessus jusqu'à 3 jours. Mon application utilise des fragments . L'un de ces fragments doit afficher une carte de l'API Google Maps V2 pour Android.
Actuellement, j'utilise un MapFragment, mais sans surprise, un fragment dans un fragment n'est pas une bonne idée, mais cela fonctionne, la carte s'affiche, je peux l'éditer mais quand je change de fragment principal et que je reviens dessus.
Causé par: Java.lang.IllegalArgumentException: ligne de fichier XML binaire # 59: ID dupliqué 0x7f070041, balise null ou id parent 0x7f070040 avec un autre fragment pour com.google.Android.gms.maps.MapFragment
sur Android.app.Activity.onCreateView (Activity.Java:4252)
sur Android.view.LayoutInflater.createViewFromTag (LayoutInflater.Java:673)
C’est la cause lorsque je vais sur un autre fragment et que je reviens à celui qui contient la carte . Je cherche jusqu’à 3 jours pour résoudre ce problème mais aucun bon résultat.
Pour résumer pour vous, j'ai une activité qui appelle un fragment qui contient un MapFragment dans le fichier de mise en page . Si vous avez besoin de plus d'informations, demandez simplement :)
Merci
Edit: Voici le code pour changer le fragment dans l'activité principale
private void swtichFragment(Fragment fragment, Bundle bundle)
{
fragment.setBundle(this, bundle);
FragmentManager fragmentManager = getFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
fragmentTransaction.replace(R.id.rightFragmentPlaceHolder, fragment);
fragmentTransaction.commit();
mRightFragment = fragment;
}
Utilisez SupportMapFragment pour surmonter cette erreur:
En fragmentation
<fragment
Android:id="@+id/googleMap"
Android:name="com.google.Android.gms.maps.SupportMapFragment"
Android:layout_width="match_parent"
Android:layout_height="match_parent" />
Dans votre fragment onCreateView
SupportMapFragment mapFragment = (SupportMapFragment) getChildFragmentManager().findFragmentById(R.id.googleMap);
if (mapFragment != null) {
mapFragment.getMapAsync(this);
}
Puisque votre disposition est dans la disposition Fragment's
, la valeur SupportMapFragment
est donc la disposition enfant de votre fragment. Utilisez donc getChildFragmentManager()
qui est Fragment's FragmentManager
Pour afficher MapFragment à l'intérieur du fragment (NestedFragment): À ce stade, je pense que vous avez
où.xml
<LinearLayout
xmlns:Android="http://schemas.Android.com/apk/res/Android"
xmlns:map="http://schemas.Android.com/apk/res-auto"
Android:layout_width="match_parent"
Android:layout_height="match_parent"
Android:gravity="center"
Android:orientation="vertical" >
<FrameLayout
Android:layout_width="match_parent"
Android:layout_height="0dp"
Android:layout_weight="1.03"
Android:name="com.google.Android.gms.maps.SupportMapFragment"
Android:id="@+id/mapwhere" />
<TextView
Android:layout_width="match_parent"
Android:layout_height="wrap_content"/>
</LinearLayout>
classe:
public class WhereFragment extends SupportMapFragment {
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
{
super.onCreateView(inflater, container, savedInstanceState);
View root = inflater.inflate(R.layout.where, null, false);
initilizeMap();
return root;
}
private void initilizeMap()
{
mSupportMapFragment = (SupportMapFragment) getFragmentManager().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)
{
googleMap = mSupportMapFragment.getMap();
if (googleMap != null)
googleMap.setOnMapClickListener(new OnMapClickListener()
{
@Override
public void onMapClick(LatLng point)
{
//TODO: your onclick stuffs
}
});
}
}
}
Documentation:
Fragments imbriqués Vous pouvez maintenant incorporer des fragments dans des fragments. C'est utile pour une variété de situations dans lesquelles vous voulez placer dynamique et des composants d'interface utilisateur réutilisables dans un composant d'interface utilisateur qui est lui-même dynamique et réutilisable. Par exemple, si vous utilisez ViewPager pour créer des fragments qui glissent à gauche et à droite et consomment la majorité de l’écran, vous pouvez maintenant insérer des fragments dans chaque page de fragment.
Pour imbriquer un fragment, appelez simplement getChildFragmentManager () sur le fichier Fragment dans lequel vous voulez ajouter un fragment. Ceci retourne un FragmentManager que vous pouvez utiliser comme vous le faites normalement à partir du fichier activité de niveau supérieur pour créer des transactions de fragment. Par exemple, Voici du code qui ajoute un fragment à partir d’un fragment existant classe:
Fragment videoFragment = new VideoPlayerFragment (); FragmentTransaction transaction = getChildFragmentManager (). beginTransaction (); transaction.add (R.id.video_fragment, videoFragment) .commit (); De dans un fragment imbriqué, vous pouvez obtenir une référence au parent fragment en appelant getParentFragment ().
La bibliothèque de support Android prend également en charge les fragments imbriqués, de sorte que vous peut implémenter des conceptions de fragments imbriqués sur Android 1.6 et supérieur.
Remarque: Vous ne pouvez pas gonfler une mise en page dans un fragment lorsque cette mise en page comprend a. Les fragments imbriqués ne sont pris en charge que lorsqu'ils sont ajoutés à un fragment dynamiquement.
source: http://developer.Android.com/about/versions/Android-4.2.html#NestedFragments
Cela corrigera aussi pour:
11-06 11:36:01.509: E/AndroidRuntime(6309): FATAL EXCEPTION: main
11-06 11:36:01.509: E/AndroidRuntime(6309): Android.view.InflateException: Binary XML file line #9: Error inflating class fragment
11-06 11:36:01.509: E/AndroidRuntime(6309): at Android.view.LayoutInflater.createViewFromTag(LayoutInflater.Java:710)
11-06 11:36:01.509: E/AndroidRuntime(6309): at Android.view.LayoutInflater.rInflate(LayoutInflater.Java:752)
11-06 11:36:01.509: E/AndroidRuntime(6309): at Android.view.LayoutInflater.rInflate(LayoutInflater.Java:760)
11-06 11:36:01.509: E/AndroidRuntime(6309): at Android.view.LayoutInflater.rInflate(LayoutInflater.Java:760)
11-06 11:36:01.509: E/AndroidRuntime(6309): at Android.view.LayoutInflater.rInflate(LayoutInflater.Java:760)
11-06 11:36:01.509: E/AndroidRuntime(6309): at Android.view.LayoutInflater.rInflate(LayoutInflater.Java:760)
11-06 11:36:01.509: E/AndroidRuntime(6309): at Android.view.LayoutInflater.inflate(LayoutInflater.Java:495)
11-06 11:36:01.509: E/AndroidRuntime(6309): at Android.view.LayoutInflater.inflate(LayoutInflater.Java:397)
11-06 11:36:01.509: E/AndroidRuntime(6309): at com.abc.Android.ui.WhereFragment.onCreateView(WhereFragment.Java:60)
11-06 11:36:01.509: E/AndroidRuntime(6309): at Android.support.v4.app.Fragment.performCreateView(Fragment.Java:1500)
11-06 11:36:01.509: E/AndroidRuntime(6309): at Android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.Java:927)
11-06 11:36:01.509: E/AndroidRuntime(6309): at Android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.Java:1104)
11-06 11:36:01.509: E/AndroidRuntime(6309): at Android.support.v4.app.BackStackRecord.run(BackStackRecord.Java:682)
11-06 11:36:01.509: E/AndroidRuntime(6309): at a ...
SupportMapFragment mSupportMapFragment;
private GoogleMap googleMap;
int ZOOM_LEVEL=15;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View mTrackView = inflater
.inflate(R.layout.mylayout, container, false);
mSupportMapFragment = SupportMapFragment.newInstance();
FragmentTransaction fragmentTransaction = getChildFragmentManager().beginTransaction();
fragmentTransaction.add(R.id.mapwhere, mSupportMapFragment);
fragmentTransaction.commit();
return mTrackView;
}
@Override
public void onStart() {
// TODO Auto-generated method stub
super.onStart();
if(mSupportMapFragment!=null){
googleMap = mSupportMapFragment.getMap();
if(googleMap!=null){
googleMap.setMapType(GoogleMap.MAP_TYPE_NORMAL);
googleMap.getUiSettings().setMyLocationButtonEnabled(false);
googleMap.setMyLocationEnabled(false);
CameraUpdate cameraUpdate = CameraUpdateFactory.newLatLngZoom(
new LatLng(12.12122,
17.22323), ZOOM_LEVEL);
googleMap.animateCamera(cameraUpdate);
}
}
}
<LinearLayout
xmlns:Android="http://schemas.Android.com/apk/res/Android"
xmlns:map="http://schemas.Android.com/apk/res-auto"
Android:layout_width="match_parent"
Android:layout_height="match_parent"
Android:gravity="center"
Android:orientation="vertical" >
<FrameLayout
Android:layout_width="match_parent"
Android:layout_height="0dp"
Android:layout_weight="1.03"
Android:id="@+id/mapwhere" />
<TextView
Android:layout_width="match_parent"
Android:layout_height="wrap_content"/>
</LinearLayout>
Après beaucoup d’erreurs, j’ai finalement fait, voici ma classe de fragments MapView: -
import Android.content.Context;
import Android.location.Location;
import Android.location.LocationListener;
import Android.location.LocationManager;
import Android.os.Bundle;
import Android.support.v4.app.Fragment;
import Android.util.Log;
import Android.view.LayoutInflater;
import Android.view.View;
import Android.view.ViewGroup;
import Android.widget.Toast;
import com.google.Android.gms.maps.CameraUpdateFactory;
import com.google.Android.gms.maps.GoogleMap;
import com.google.Android.gms.maps.GoogleMap.OnMapClickListener;
import com.google.Android.gms.maps.MapFragment;
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;
import com.serveroverload.yago.R;
/**
* @author 663918
*
*/
public class HomeFragment extends Fragment implements LocationListener {
// Class to do operations on the Map
GoogleMap googleMap;
private LocationManager locationManager;
public static Fragment newInstance() {
return new HomeFragment();
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.home_fragment, container, false);
Bundle bdl = getArguments();
// setuping locatiomanager to perfrom location related operations
locationManager = (LocationManager) getActivity().getSystemService(
Context.LOCATION_SERVICE);
// Requesting locationmanager for location updates
locationManager.requestLocationUpdates(
LocationManager.NETWORK_PROVIDER, 1, 1, this);
// To get map from MapFragment from layout
googleMap = ((MapFragment) getActivity().getFragmentManager()
.findFragmentById(R.id.map)).getMap();
// To change the map type to Satellite
// googleMap.setMapType(GoogleMap.MAP_TYPE_SATELLITE);
// To show our current location in the map with dot
// googleMap.setMyLocationEnabled(true);
// To listen action whenever we click on the map
googleMap.setOnMapClickListener(new OnMapClickListener() {
@Override
public void onMapClick(LatLng latLng) {
/*
* LatLng:Class will give us selected position lattigude and
* longitude values
*/
Toast.makeText(getActivity(), latLng.toString(),
Toast.LENGTH_LONG).show();
}
});
changeMapMode(3);
// googleMap.setSatellite(true);
googleMap.setTrafficEnabled(true);
googleMap.setBuildingsEnabled(true);
googleMap.setMyLocationEnabled(true);
return v;
}
private void doZoom() {
if (googleMap != null) {
googleMap.animateCamera(CameraUpdateFactory.newLatLngZoom(
new LatLng(18.520430, 73.856744), 17));
}
}
private void changeMapMode(int mapMode) {
if (googleMap != null) {
switch (mapMode) {
case 0:
googleMap.setMapType(GoogleMap.MAP_TYPE_NONE);
break;
case 1:
googleMap.setMapType(GoogleMap.MAP_TYPE_NORMAL);
break;
case 2:
googleMap.setMapType(GoogleMap.MAP_TYPE_SATELLITE);
break;
case 3:
googleMap.setMapType(GoogleMap.MAP_TYPE_TERRAIN);
break;
case 4:
googleMap.setMapType(GoogleMap.MAP_TYPE_HYBRID);
break;
default:
break;
}
}
}
private void createMarker(double latitude, double longitude) {
// double latitude = 17.385044;
// double longitude = 78.486671;
// lets place some 10 random markers
for (int i = 0; i < 10; i++) {
// random latitude and logitude
double[] randomLocation = createRandLocation(latitude, longitude);
// Adding a marker
MarkerOptions marker = new MarkerOptions().position(
new LatLng(randomLocation[0], randomLocation[1])).title(
"Hello Maps " + i);
Log.e("Random", "> " + randomLocation[0] + ", " + randomLocation[1]);
// changing marker color
if (i == 0)
marker.icon(BitmapDescriptorFactory
.defaultMarker(BitmapDescriptorFactory.HUE_Azure));
if (i == 1)
marker.icon(BitmapDescriptorFactory
.defaultMarker(BitmapDescriptorFactory.HUE_BLUE));
if (i == 2)
marker.icon(BitmapDescriptorFactory
.defaultMarker(BitmapDescriptorFactory.HUE_CYAN));
if (i == 3)
marker.icon(BitmapDescriptorFactory
.defaultMarker(BitmapDescriptorFactory.HUE_GREEN));
if (i == 4)
marker.icon(BitmapDescriptorFactory
.defaultMarker(BitmapDescriptorFactory.HUE_Magenta));
if (i == 5)
marker.icon(BitmapDescriptorFactory
.defaultMarker(BitmapDescriptorFactory.HUE_ORANGE));
if (i == 6)
marker.icon(BitmapDescriptorFactory
.defaultMarker(BitmapDescriptorFactory.HUE_RED));
if (i == 7)
marker.icon(BitmapDescriptorFactory
.defaultMarker(BitmapDescriptorFactory.HUE_ROSE));
if (i == 8)
marker.icon(BitmapDescriptorFactory
.defaultMarker(BitmapDescriptorFactory.HUE_Violet));
if (i == 9)
marker.icon(BitmapDescriptorFactory
.defaultMarker(BitmapDescriptorFactory.HUE_YELLOW));
googleMap.addMarker(marker);
// Move the camera to last position with a zoom level
if (i == 9) {
CameraPosition cameraPosition = new CameraPosition.Builder()
.target(new LatLng(randomLocation[0], randomLocation[1]))
.zoom(15).build();
googleMap.animateCamera(CameraUpdateFactory
.newCameraPosition(cameraPosition));
}
}
}
/*
* creating random postion around a location for testing purpose only
*/
private double[] createRandLocation(double latitude, double longitude) {
return new double[] { latitude + ((Math.random() - 0.5) / 500),
longitude + ((Math.random() - 0.5) / 500),
150 + ((Math.random() - 0.5) * 10) };
}
@Override
public void onLocationChanged(Location location) {
if (null != googleMap) {
// To get lattitude value from location object
double latti = location.getLatitude();
// To get longitude value from location object
double longi = location.getLongitude();
// To hold lattitude and longitude values
LatLng position = new LatLng(latti, longi);
createMarker(latti, longi);
// Creating object to pass our current location to the map
MarkerOptions markerOptions = new MarkerOptions();
// To store current location in the markeroptions object
markerOptions.position(position);
// Zooming to our current location with zoom level 17.0f
googleMap.animateCamera(CameraUpdateFactory.newLatLngZoom(position,
17f));
// adding markeroptions class object to the map to show our current
// location in the map with help of default marker
googleMap.addMarker(markerOptions);
}
}
@Override
public void onStatusChanged(String provider, int status, Bundle extras) {
// TODO Auto-generated method stub
}
@Override
public void onProviderEnabled(String provider) {
// TODO Auto-generated method stub
}
@Override
public void onProviderDisabled(String provider) {
// TODO Auto-generated method stub
}
@Override
public void onDestroyView() {
// TODO Auto-generated method stub
super.onDestroyView();
locationManager.removeUpdates(this);
Android.app.Fragment fragment = getActivity().getFragmentManager()
.findFragmentById(R.id.map);
if (null != fragment) {
Android.app.FragmentTransaction ft = getActivity()
.getFragmentManager().beginTransaction();
ft.remove(fragment);
ft.commit();
}
}
}
Mon fichier XML ressemble à ceci: -
<?xml version="1.0" encoding="utf-8"?>
<fragment xmlns:Android="http://schemas.Android.com/apk/res/Android"
Android:id="@+id/map"
Android:name="com.google.Android.gms.maps.MapFragment"
Android:layout_width="match_parent"
Android:layout_height="match_parent" />
Et le résultat ressemble à ceci: -
La chose la plus importante à noter est que ne pas mélanger app.Fragment avec v4.Fragments sinon l'application va planter.
Comme vous pouvez le constater, j'ai utilisé app.Fragment pour attacher et supprimer mon fragment MapView.
J'espère que ça va aider quelqu'un