54 votes

Erreur lors de l'ouverture de SupportMapFragment pour la deuxième fois

Lorsque j'ouvre mon supportMapFragment (Android maps v2) pour la deuxième fois (en appelant setContentView), l'erreur suivante apparaît:

 01-28 16:27:21.374: E/AndroidRuntime(32743): FATAL EXCEPTION: main
01-28 16:27:21.374: E/AndroidRuntime(32743): android.view.InflateException: Binary XML file line #6: Error inflating class fragment
01-28 16:27:21.374: E/AndroidRuntime(32743):    at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:704)
01-28 16:27:21.374: E/AndroidRuntime(32743):    at android.view.LayoutInflater.rInflate(LayoutInflater.java:746)
01-28 16:27:21.374: E/AndroidRuntime(32743):    at android.view.LayoutInflater.inflate(LayoutInflater.java:489)
01-28 16:27:21.374: E/AndroidRuntime(32743):    at android.view.LayoutInflater.inflate(LayoutInflater.java:396)
01-28 16:27:21.374: E/AndroidRuntime(32743):    at android.view.LayoutInflater.inflate(LayoutInflater.java:352)
01-28 16:27:21.374: E/AndroidRuntime(32743):    at android.view.View.inflate(View.java:16119)
01-28 16:27:21.374: E/AndroidRuntime(32743):    at mypackage.MyView.<init>(HitsView.java:26)
01-28 16:27:21.374: E/AndroidRuntime(32743):    at mypackage.MenuListFragment.onItemClick(MenuListFragment.java:133)
01-28 16:27:21.374: E/AndroidRuntime(32743):    at android.widget.AdapterView.performItemClick(AdapterView.java:298)
01-28 16:27:21.374: E/AndroidRuntime(32743):    at android.widget.AbsListView.performItemClick(AbsListView.java:1086)
01-28 16:27:21.374: E/AndroidRuntime(32743):    at android.widget.AbsListView$PerformClick.run(AbsListView.java:2855)
01-28 16:27:21.374: E/AndroidRuntime(32743):    at android.widget.AbsListView$1.run(AbsListView.java:3529)
01-28 16:27:21.374: E/AndroidRuntime(32743):    at android.os.Handler.handleCallback(Handler.java:615)
01-28 16:27:21.374: E/AndroidRuntime(32743):    at android.os.Handler.dispatchMessage(Handler.java:92)
01-28 16:27:21.374: E/AndroidRuntime(32743):    at android.os.Looper.loop(Looper.java:137)
01-28 16:27:21.374: E/AndroidRuntime(32743):    at android.app.ActivityThread.main(ActivityThread.java:4745)
01-28 16:27:21.374: E/AndroidRuntime(32743):    at java.lang.reflect.Method.invokeNative(Native Method)
01-28 16:27:21.374: E/AndroidRuntime(32743):    at java.lang.reflect.Method.invoke(Method.java:511)
01-28 16:27:21.374: E/AndroidRuntime(32743):    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:786)
01-28 16:27:21.374: E/AndroidRuntime(32743):    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553)
01-28 16:27:21.374: E/AndroidRuntime(32743):    at dalvik.system.NativeStart.main(Native Method)
01-28 16:27:21.374: E/AndroidRuntime(32743): Caused by: java.lang.IllegalArgumentException: Binary XML file line #6: Duplicate id 0x7f04003b, tag null, or parent id 0x0 with another fragment for com.google.android.gms.maps.SupportMapFragment
01-28 16:27:21.374: E/AndroidRuntime(32743):    at android.support.v4.app.FragmentActivity.onCreateView(FragmentActivity.java:285)
01-28 16:27:21.374: E/AndroidRuntime(32743):    at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:676)
01-28 16:27:21.374: E/AndroidRuntime(32743):    ... 20 more
 

Le fichier XML:

 <?xml version="1.0" encoding="utf-8"?>
<RelativeLayout 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" >
    <fragment
        android:id="@+id/hits_map"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        class="com.google.android.gms.maps.SupportMapFragment"
        map:mapType="normal"
        map:uiZoomControls="false"
        map:uiZoomGestures="true"
        map:cameraZoom="13"
        map:uiRotateGestures="true"
        map:uiTiltGestures="true"/>
</RelativeLayout>
 

MyView.class:

 public class MyView extends RelativeLayout {
    private GoogleMap map;

    public MyView(Context context, FragmentActivity activity) {
        super(context);
        inflate(activity, R.layout.activity_hits, this);
        this.map = ((SupportMapFragment) activity.getSupportFragmentManager()
            .findFragmentById(R.id.hits_map)).getMap();
    }
}
 

Je n'ai aucune idée de ce que cette erreur signifie. Quelqu'un peut-il expliquer cela?

83voto

Kaleb Points 954

Mise à jour: Comme une solution alternative (qui je pense est beaucoup mieux), vous pouvez utiliser une MapView qui est décrit: ici

J'ai couru à travers un problème similaire, tout en travaillant avec un des onglets de mise en œuvre. Avec Google Maps V2, vous êtes coincé avec le SupportMapFragment, donc, à l'aide de la MapView n'est pas une option. Entre juanmeanwhile post et commentaire n ° 1 disponible ici (https://code.google.com/p/gmaps-api-issues/issues/detail?id=5064#c1), j'ai réussi à comprendre ce que je faisais mal.

Donc, pour quelqu'un d'autre se l'id en Double erreur, assurez-vous de déclarer le fragment par programmation, pas en XML. Cela signifie probablement de nidification des mises en page.

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout 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" >

<!-- Lots of fancy layout -->   

<RelativeLayout
        android:id="@+id/map"
        android:layout_width="match_parent"
        android:layout_height="wrap_content">
    </RelativeLayout>
</RelativeLayout>

Ensuite, vous devez créer votre fragment par programmation, mais il doit être fait avec soin en tenant compte de l'Fragments du cycle de vie (http://developer.android.com/reference/android/app/Fragment.html#getChildFragmentManager()). Pour s'assurer que tout est créé, au bon moment, votre code devrait ressembler à ceci (prises de commentaire #1).

public class MyFragment extends Fragment {

private SupportMapFragment fragment;
private GoogleMap map;

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

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

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

J'espère que cela permet de gagner du temps.

51voto

juanmeanwhile Points 821

Au lieu de déclarer de SupportMapFragment dans la présentation, faites-le par programme et assurez-vous d'utiliser getChildFragmentMananger au lieu du classique getFragmentManager () pour créer le fragment.

   mMapFragment = SupportMapFragment.newInstance();
    FragmentTransaction fragmentTransaction =
             getChildFragmentManager().beginTransaction();
     fragmentTransaction.add(R.id.map_root, mMapFragment);
     fragmentTransaction.commit(); 
 

Conservez cette mMapFragment SupportMapFragment car vous en aurez besoin pour récupérer l'objet GoogleMap:

   GoogleMap map = mMapFragment.getMap();
 

24voto

Jaroslav Points 181

J'ai passé une demi-journée à résoudre ce problème et je n'ai trouvé qu'une solution de contournement. Remplacer votre onCreate méthode en YourFragment classe:

 public void onCreate(Bundle savedInstanceState) {
    setRetainInstance(true); 
    super.onCreate(savedInstanceState);     
}
 

Et remplacez votre méthode onDestroy :

 @Override
public void onDestroyView() {
    super.onDestroyView();
    try {
        SupportMapFragment fragment = (SupportMapFragment) getActivity()
                                          .getSupportFragmentManager().findFragmentById(
                                              R.id.multi_inns_on_map);
        if (fragment != null) getFragmentManager().beginTransaction().remove(fragment).commit();

    } catch (IllegalStateException e) {
        //handle this situation because you are necessary will get 
        //an exception here :-(
    }
}
 

2voto

Sterling Diaz Points 316

J'avais passé toute cette journée à chercher la solution à ce problème, la lecture de tous les workaroung ici, et j'ai trouvé cette façon de résoudre les problèmes. Je vais poster tout le code, parce que cette question ne manque qu'une réponse complète, juste un petit morceau de code qui correspond à un scénario et n'aident personne.

public class LocationFragment extends Fragment implements View.OnClickListener {

    private GoogleMap googleMap;
    private static View rootView;
    private SupportMapFragment supportMapFragment;

    public LocationFragment() {
    }

    @Override
    public void onDestroyView() {
        super.onDestroyView();
    }

    @Override
    public void onCreate(Bundle savedInstanceState) {
        setRetainInstance(true);
        super.onCreate(savedInstanceState);
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        if(savedInstanceState == null) {

            if (rootView != null) {
                ViewGroup parent = (ViewGroup) rootView.getParent();
                if (parent != null)
                    parent.removeView(rootView);
            }

            try{
                if(rootView == null)
                {
                    rootView = inflater.inflate(R.layout.fragment_location, container, false);
                }

                supportMapFragment = (SupportMapFragment) getFragmentManager().findFragmentById(R.id.map);
                LocationUtility locationUtility = LocationUtility.getInstance(context);
                GoogleMap googleMap =  locationUtility.initilizeMap(supportMapFragment);

              //More code

            } catch (Exception e)
            {
                e.printStackTrace();
            }
        }

        return rootView;
    }

}

Par le débogage, vous remarquerez qu'il n'a pas d'importance comment le fragment fonctionne, vous n'avez pas besoin de botter le onDestroyMethod, etc, étant donné que la validation de la valeur null, tout fonctionne avec l'instance actuelle de l'objet.

Profitez-en! ;)

1voto

user2771209 Points 1

J'ai rencontré ce problème et j'ai trouvé dans mes journaux Android que mon accélération matérielle n'était pas activée. Après l'avoir activé dans mon manifeste Android, l'affichage des cartes à plusieurs reprises n'était plus un problème. J'utilisais un émulateur x86.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X