Android – SupportMapFragment与GoogleMaps API 2.0给IllegalArgumentException

我正在尝试使用为Android提供的最新的Map API 2.0。 我正在使用支持库,因为我想支持Android 2.2。 以下是我的代码:

主要活动类

public class MainActivity extends FragmentActivity { public FragmentManager fManager ; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); fManager = getSupportFragmentManager(); Button showMapButton = (Button) findViewById(R.id.showMapButton); showMapButton.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { loadMapFragment(); } }); } private void loadMapFragment() { MapPageFragment plotterFragment = new MapPageFragment(); FragmentTransaction ft = fManager.beginTransaction(); ft.replace(R.id.allFragmentsFrameLayout, plotterFragment); ft.addToBackStack(null); ft.commit(); } @Override public boolean onCreateOptionsMenu(Menu menu) { getMenuInflater().inflate(R.menu.activity_main, menu); return true; } } 

主要活动布局文件

 <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" tools:context=".MainActivity" > <Button android:id="@+id/showMapButton" android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="Show Map" android:layout_marginLeft="30dp" android:layout_marginRight="30dp" android:layout_marginTop="30dp" android:layout_alignParentTop="true" /> <FrameLayout android:id="@+id/allFragmentsFrameLayout" android:layout_width="fill_parent" android:layout_height="fill_parent" android:layout_alignParentTop="true"> <!-- Put fragments dynamically --> </FrameLayout> </RelativeLayout> 

地图片段类

 public class MapPageFragment extends SupportMapFragment { @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { super.onCreateView(inflater, container, savedInstanceState); return inflater.inflate(R.layout.map_fragment_layout, container, false); } @Override public void onViewCreated(View view, Bundle savedInstanceState) { super.onViewCreated(view, savedInstanceState); } } 

地图片段布局

 <?xml version="1.0" encoding="utf-8"?> <fragment xmlns:android="http://schemas.android.com/apk/res/android" xmlns:map="http://schemas.android.com/apk/res-auto" android:id="@+id/map" android:layout_width="fill_parent" android:layout_height="fill_parent" class="com.google.android.gms.maps.SupportMapFragment" map:uiCompass="true" map:mapType= "normal" map:uiRotateGestures="true" map:uiScrollGestures="true" map:uiTiltGestures="true" map:uiZoomControls="true" map:uiZoomGestures="true" /> 

Android清单文件

 <?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.mapfragmentexample" android:versionCode="1" android:versionName="1.0" > <uses-sdk android:minSdkVersion="8" android:targetSdkVersion="16" /> <permission android:name="com.plotter.permission.MAPS_RECEIVE" android:protectionLevel="signature"/> <uses-permission android:name="com.plotter.permission.MAPS_RECEIVE"/> <uses-permission android:name="android.permission.INTERNET"/> <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/> <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/> <uses-permission android:name="com.google.android.providers.gsf.permission.READ_GSERVICES"/> <uses-feature android:glEsVersion="0x00020000" android:required="true"/> <application android:allowBackup="true" android:icon="@drawable/ic_launcher" android:label="@string/app_name" android:theme="@style/AppTheme" > <activity android:name=".MainActivity" android:label="@string/app_name" > <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> <meta-data android:name="com.google.android.maps.v2.API_KEY" android:value="AIzaSyA5FtIeLQ1gGUihZIZPQVi3Yz_0l4NG9PY"/> </application> </manifest> 

一切工作正常,第一次。 即当我点击Show Mapbutton时,地图片段被加载并显示地图。 当我按下button,地图片段被卸载,我可以再次看到Show Mapbutton。

我再次按下“ Show Mapbutton时遇到问题。 我得到以下错误:

 FATAL EXCEPTION: main android.view.InflateException: Binary XML file line #2: Error inflating class fragment at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:699) at android.view.LayoutInflater.inflate(LayoutInflater.java:468) at android.view.LayoutInflater.inflate(LayoutInflater.java:397) at com.mapfragmentexample.MapPageFragment.onCreateView(MapPageFragment.java:17) at android.support.v4.app.Fragment.performCreateView(Fragment.java:1460) at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:911) at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1088) at android.support.v4.app.BackStackRecord.run(BackStackRecord.java:682) at android.support.v4.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:1444) at android.support.v4.app.FragmentManagerImpl$1.run(FragmentManager.java:429) at android.os.Handler.handleCallback(Handler.java:605) at android.os.Handler.dispatchMessage(Handler.java:92) at android.os.Looper.loop(Looper.java:137) at android.app.ActivityThread.main(ActivityThread.java:4503) at java.lang.reflect.Method.invokeNative(Native Method) at java.lang.reflect.Method.invoke(Method.java:511) at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:809) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:576) at dalvik.system.NativeStart.main(Native Method) Caused by: java.lang.IllegalArgumentException: Binary XML file line #2: Duplicate id 0x7f040006, tag null, or parent id 0x0 with another fragment for com.google.android.gms.maps.SupportMapFragment at android.support.v4.app.FragmentActivity.onCreateView(FragmentActivity.java:285) at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:671) ... 18 more 

我没有得到我错了或丢失任何东西的地方。

你可以修复这个,如果你删除onDestroyView() 所有嵌套片段 。 不知道这是否是一个合适的解决scheme。

 public void onDestroyView() { super.onDestroyView(); Fragment fragment = (getFragmentManager().findFragmentById(R.id.map)); FragmentTransaction ft = getActivity().getSupportFragmentManager().beginTransaction(); ft.remove(fragment); ft.commit(); } 

并像往常一样在onCreateView()

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

您需要使用getChildFragmentManager()通过xml添加SupportMapFragment。

有关“为什么”,请参阅官方文档: http : //developer.android.com/about/versions/android-4.2.html#NestedFragments

看看我的答案在这里: https : //stackoverflow.com/a/15512285/2183804

当布局包含片段时,不能将布局膨胀成片段 。 只有在dynamic添加到片段时才支持嵌套片段。 更多细节在这里 !

使用这个解决scheme(类似于其他):

 public void onDestroyView() { FragmentManager fm = getActivity().getSupportFragmentManager(); Fragment fragment = (fm.findFragmentById(R.id.map)); if (fragment.isResumed()) { FragmentTransaction ft = fm.beginTransaction(); ft.remove(fragment); ft.commit(); } super.onDestroyView(); } 

在使用if(fragment.isResumed)之前,我遇到了问题。

我和SherlockFragments一样在JakeWhartonViewPagerIndicatore中面临同样的问题。 这里是示例TestFragment与解决的问题,感谢纳塔利娅提供上述解决scheme。 你的片段可能与我的有点不同。

参考: 使ActionBarSherlock和ViewPagerIndicator发挥不错

祝你好运..!!

 package com.example.vpiabstest; import android.os.Bundle; import android.support.v4.app.Fragment; import android.support.v4.app.FragmentTransaction; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.TextView; import com.actionbarsherlock.app.SherlockFragment; public class TestFragment extends SherlockFragment { private String mContent = "???"; private String text; private static final String KEY_TAB_NUM = "key.tab.num"; public static TestFragment newInstance(String text) { TestFragment fragment = new TestFragment(); // Supply num input as an argument. Bundle args = new Bundle(); args.putString(KEY_TAB_NUM, text); fragment.setArguments(args); return fragment; } @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { text = getString(R.string.tab_page_num) + mContent; View view = null; if(text.contains("2")) { view = inflater.inflate(R.layout.pinpoints_list, null); } else if(text.contains("1")) { view = inflater.inflate(R.layout.main_fragment_activity, null); } else { view = inflater.inflate(R.layout.activity_main, null); ((TextView)view.findViewById(R.id.text)).setText(text); } return view; } @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); mContent = getArguments() != null ? getArguments().getString(KEY_TAB_NUM) : "???"; } public void onDestroyView() { super.onDestroyView(); // Your Programing skills goes here if(text == null || !text.contains("1")) { return; } // Do Not Miss this try { Fragment fragment = (getFragmentManager().findFragmentById(R.id.map_fragment)); FragmentTransaction ft = getActivity().getSupportFragmentManager().beginTransaction(); ft.remove(fragment); ft.commit(); } catch (Exception e) { e.printStackTrace(); } } } 

在我们加载时,在你的activity的onCreate() dialog.SetContentView()方法中使用dialog.SetContentView()方法。

对话框再次加载对话框不是整个活动的生命周期,并导致它重复的id的例外。

尝试一下。

尝试这个

地图片段布局

 <?xml version="1.0" encoding="utf-8"?> <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:layout_width="fill_parent" android:layout_height="fill_parent" map:uiCompass="true" map:mapType= "normal" map:uiRotateGestures="true" map:uiScrollGestures="true" map:uiTiltGestures="true" map:uiZoomControls="true" map:uiZoomGestures="true" tools:context="the.package.name.of.mappagefragment.MapPageFragment" /> 

映射片段类

 public class MapPageFragment extends SupportMapFragment { @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { View rootView = super.onCreateView(inflater, container, savedInstanceState); if (rootView == null) { rootView = inflater.inflate(R.layout.map_fragment_layout, container, false); } return rootView; } @Override public void onViewCreated(View view, Bundle savedInstanceState) { super.onViewCreated(view, savedInstanceState); } } 

我用纳塔利娅的反应,但有时打破了应用程序。 使用这一个,它完美无缺地工作。

 @Override public void onDestroyView() { try{ FragmentTransaction transaction = getSupportFragmentManager() .beginTransaction(); transaction.remove(nestedFragment); transaction.commit(); }catch(Exception e){ } super.onDestroyView(); } 

https://stackoverflow.com/a/7953801/3364157

 Fragment fragment = (getChildFragmentManager().findFragmentById(R.id.mapview)); FragmentTransaction ft = getActivity().getSupportFragmentManager().beginTransaction(); ft.remove(fragment); ft.commit(); 

使用这个节省一天。

使用意图标志:

 intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK); 

当调用主要活动。

我有同样的问题。 尝试添加…

 android:name="com.mapfragmentexample.MapPageFragment" 

…在布局文件中fragment