问题描述
我正在使用以下代码来加载片段,具体取决于在Navigation抽屉上选择了哪个项目,但是MapFragment在其内部包含Google Map片段,并且在尝试第二次打开后崩溃.
.这是我正在使用的代码:
@Override public void onNavigationDrawerItemSelected(int position) { // update the main content by replacing fragments FragmentManager fragmentManager = getSupportFragmentManager(); if (position == 0) { fragmentManager.beginTransaction() .replace(R.id.container, MapFragment.newInstance("a", "b")) .commit(); } else { fragmentManager.beginTransaction() .replace(R.id.container, PlaceholderFragment.newInstance(position + 1)) .commit(); } }
这是日志:
03-01 14:18:25.870 27175-27175/com.br.appname E/﹕ Device driver API match Device driver API version: 23 User space API version: 23 03-01 14:18:25.870 27175-27175/com.br.appname E/﹕ mali: REVISION=Linux-r3p2-01rel3 BUILD_DATE=Wed Oct 30 09:36:10 KST 2013 03-01 14:19:12.655 27175-27175/com.br.appname E/AndroidRuntime﹕ FATAL EXCEPTION: main android.view.InflateException: Binary XML file line #13: Error inflating class fragment at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:719) at android.view.LayoutInflater.rInflate(LayoutInflater.java:761) at android.view.LayoutInflater.rInflate(LayoutInflater.java:769) at android.view.LayoutInflater.inflate(LayoutInflater.java:498) at android.view.LayoutInflater.inflate(LayoutInflater.java:398) at com.br.appname.fragments.MapFragment.onCreateView(MapFragment.java:74) at android.support.v4.app.Fragment.performCreateView(Fragment.java:1500) at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:927) at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1104) at android.support.v4.app.BackStackRecord.run(BackStackRecord.java:682) at android.support.v4.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:1467) at android.support.v4.app.FragmentManagerImpl$1.run(FragmentManager.java:440) at android.os.Handler.handleCallback(Handler.java:730) at android.os.Handler.dispatchMessage(Handler.java:92) at android.os.Looper.loop(Looper.java:137) at android.app.ActivityThread.main(ActivityThread.java:5419) at java.lang.reflect.Method.invokeNative(Native Method) at java.lang.reflect.Method.invoke(Method.java:525) at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1209) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1025) at dalvik.system.NativeStart.main(Native Method) Caused by: java.lang.IllegalArgumentException: Binary XML file line #13: Duplicate id 0x7f070055, tag null, or parent id 0x7f070054 with another fragment for com.google.android.gms.maps.MapFragment at android.app.Activity.onCreateView(Activity.java:4971) at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:695) at android.view.LayoutInflater.rInflate(LayoutInflater.java:761) at android.view.LayoutInflater.rInflate(LayoutInflater.java:769) at android.view.LayoutInflater.inflate(LayoutInflater.java:498) at android.view.LayoutInflater.inflate(LayoutInflater.java:398) at com.br.appname.fragments.MapFragment.onCreateView(MapFragment.java:74) at android.support.v4.app.Fragment.performCreateView(Fragment.java:1500) at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:927) at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1104) at android.support.v4.app.BackStackRecord.run(BackStackRecord.java:682) at android.support.v4.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:1467) at android.support.v4.app.FragmentManagerImpl$1.run(FragmentManager.java:440) at android.os.Handler.handleCallback(Handler.java:730) at android.os.Handler.dispatchMessage(Handler.java:92) at android.os.Looper.loop(Looper.java:137) at android.app.ActivityThread.main(ActivityThread.java:5419) at java.lang.reflect.Method.invokeNative(Native Method) at java.lang.reflect.Method.invoke(Method.java:525) at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1209) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1025) at dalvik.system.NativeStart.main(Native Method)
这仅在mapfragment中发生.占位段效果很好.
更新
fragment_map.xml
<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="com.br.remotepark.fragments.MapFragment"> <com.sothree.slidinguppanel.SlidingUpPanelLayout android:id="@+id/sliding_layout" android:layout_width="match_parent" android:layout_height="match_parent" android:gravity="bottom"> <fragment android:id="@+id/map" android:layout_width="match_parent" android:layout_height="match_parent" android:name="com.google.android.gms.maps.MapFragment" /> <LinearLayout android:layout_width="match_parent" android:layout_height="match_parent" android:background="#eee" android:orientation="vertical" android:clickable="true" android:focusable="false"> <LinearLayout android:layout_width="match_parent" android:layout_height="68dp" android:orientation="horizontal"> <TextView android:id="@+id/name" android:layout_width="0dp" android:layout_height="match_parent" android:layout_weight="1" android:textSize="14sp" android:gravity="center_vertical" android:paddingLeft="10dp" /> <Button android:id="@+id/follow" android:layout_width="wrap_content" android:layout_height="match_parent" android:textSize="14sp" android:gravity="center_vertical|right" android:paddingRight="10dp" android:paddingLeft="10dp" /> </LinearLayout> </LinearLayout> </com.sothree.slidinguppanel.SlidingUpPanelLayout> </RelativeLayout>
推荐答案
重复ID问题与使用嵌套片段的错误方式有关.
来自:版本/Android-4.2.html#NestedFragments
注意:当该布局包含<fragment>时,您不能将布局夸大成片段.嵌套片段仅在动态添加到片段时才能支持.
因此,您的fragment_map.xml不能直接包含com.google.android.gms.maps.MapFragment.用ID map_container替换为FrameLayout,然后尝试这样的东西:
public class MyFragmentWithMap extends Fragment { private MapFragment fragment; private GoogleMap map; @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { return inflater.inflate(R.layout.fragment_map, container, false); } @Override public void onActivityCreated(Bundle savedInstanceState) { super.onActivityCreated(savedInstanceState); FragmentManager fm = getChildFragmentManager(); fragment = (MapFragment) fm.findFragmentById(R.id.map_container); if (fragment == null) { fragment = MapFragment.newInstance(); fm.beginTransaction().replace(R.id.map_container, fragment).commit(); } } @Override public void onResume() { super.onResume(); setUpMapIfNeeded(); } // ... }
请注意使用getChildFragmentManager.
问题描述
I'm using the following code to load fragments depending on which item has been selected on NavigationDrawer, however the MapFragment contains Google Maps fragment inside of it and it crashes after trying to open it for the second time.
Here's the code I'm using:
@Override public void onNavigationDrawerItemSelected(int position) { // update the main content by replacing fragments FragmentManager fragmentManager = getSupportFragmentManager(); if (position == 0) { fragmentManager.beginTransaction() .replace(R.id.container, MapFragment.newInstance("a", "b")) .commit(); } else { fragmentManager.beginTransaction() .replace(R.id.container, PlaceholderFragment.newInstance(position + 1)) .commit(); } }
And here's the log:
03-01 14:18:25.870 27175-27175/com.br.appname E/﹕ Device driver API match Device driver API version: 23 User space API version: 23 03-01 14:18:25.870 27175-27175/com.br.appname E/﹕ mali: REVISION=Linux-r3p2-01rel3 BUILD_DATE=Wed Oct 30 09:36:10 KST 2013 03-01 14:19:12.655 27175-27175/com.br.appname E/AndroidRuntime﹕ FATAL EXCEPTION: main android.view.InflateException: Binary XML file line #13: Error inflating class fragment at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:719) at android.view.LayoutInflater.rInflate(LayoutInflater.java:761) at android.view.LayoutInflater.rInflate(LayoutInflater.java:769) at android.view.LayoutInflater.inflate(LayoutInflater.java:498) at android.view.LayoutInflater.inflate(LayoutInflater.java:398) at com.br.appname.fragments.MapFragment.onCreateView(MapFragment.java:74) at android.support.v4.app.Fragment.performCreateView(Fragment.java:1500) at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:927) at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1104) at android.support.v4.app.BackStackRecord.run(BackStackRecord.java:682) at android.support.v4.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:1467) at android.support.v4.app.FragmentManagerImpl$1.run(FragmentManager.java:440) at android.os.Handler.handleCallback(Handler.java:730) at android.os.Handler.dispatchMessage(Handler.java:92) at android.os.Looper.loop(Looper.java:137) at android.app.ActivityThread.main(ActivityThread.java:5419) at java.lang.reflect.Method.invokeNative(Native Method) at java.lang.reflect.Method.invoke(Method.java:525) at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1209) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1025) at dalvik.system.NativeStart.main(Native Method) Caused by: java.lang.IllegalArgumentException: Binary XML file line #13: Duplicate id 0x7f070055, tag null, or parent id 0x7f070054 with another fragment for com.google.android.gms.maps.MapFragment at android.app.Activity.onCreateView(Activity.java:4971) at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:695) at android.view.LayoutInflater.rInflate(LayoutInflater.java:761) at android.view.LayoutInflater.rInflate(LayoutInflater.java:769) at android.view.LayoutInflater.inflate(LayoutInflater.java:498) at android.view.LayoutInflater.inflate(LayoutInflater.java:398) at com.br.appname.fragments.MapFragment.onCreateView(MapFragment.java:74) at android.support.v4.app.Fragment.performCreateView(Fragment.java:1500) at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:927) at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1104) at android.support.v4.app.BackStackRecord.run(BackStackRecord.java:682) at android.support.v4.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:1467) at android.support.v4.app.FragmentManagerImpl$1.run(FragmentManager.java:440) at android.os.Handler.handleCallback(Handler.java:730) at android.os.Handler.dispatchMessage(Handler.java:92) at android.os.Looper.loop(Looper.java:137) at android.app.ActivityThread.main(ActivityThread.java:5419) at java.lang.reflect.Method.invokeNative(Native Method) at java.lang.reflect.Method.invoke(Method.java:525) at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1209) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1025) at dalvik.system.NativeStart.main(Native Method)
This happens only with the MapFragment. PlaceholderFragment works just fine.
UPDATE
fragment_map.xml
<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="com.br.remotepark.fragments.MapFragment"> <com.sothree.slidinguppanel.SlidingUpPanelLayout android:id="@+id/sliding_layout" android:layout_width="match_parent" android:layout_height="match_parent" android:gravity="bottom"> <fragment android:id="@+id/map" android:layout_width="match_parent" android:layout_height="match_parent" android:name="com.google.android.gms.maps.MapFragment" /> <LinearLayout android:layout_width="match_parent" android:layout_height="match_parent" android:background="#eee" android:orientation="vertical" android:clickable="true" android:focusable="false"> <LinearLayout android:layout_width="match_parent" android:layout_height="68dp" android:orientation="horizontal"> <TextView android:id="@+id/name" android:layout_width="0dp" android:layout_height="match_parent" android:layout_weight="1" android:textSize="14sp" android:gravity="center_vertical" android:paddingLeft="10dp" /> <Button android:id="@+id/follow" android:layout_width="wrap_content" android:layout_height="match_parent" android:textSize="14sp" android:gravity="center_vertical|right" android:paddingRight="10dp" android:paddingLeft="10dp" /> </LinearLayout> </LinearLayout> </com.sothree.slidinguppanel.SlidingUpPanelLayout> </RelativeLayout>
推荐答案
Duplicate ID issue is related to incorrect way of using nested fragments.
From: http://developer.android.com/about/versions/android-4.2.html#NestedFragments
Note: You cannot inflate a layout into a fragment when that layout includes a <fragment>. Nested fragments are only supported when added to a fragment dynamically.
So your fragment_map.xml cannot directly contain com.google.android.gms.maps.MapFragment. Replace it with FrameLayout with id map_container and try something like this:
public class MyFragmentWithMap extends Fragment { private MapFragment fragment; private GoogleMap map; @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { return inflater.inflate(R.layout.fragment_map, container, false); } @Override public void onActivityCreated(Bundle savedInstanceState) { super.onActivityCreated(savedInstanceState); FragmentManager fm = getChildFragmentManager(); fragment = (MapFragment) fm.findFragmentById(R.id.map_container); if (fragment == null) { fragment = MapFragment.newInstance(); fm.beginTransaction().replace(R.id.map_container, fragment).commit(); } } @Override public void onResume() { super.onResume(); setUpMapIfNeeded(); } // ... }
Note the use of getChildFragmentManager.