这个问题,是在使用其他sdk进行开发时出现的,觉得比较典型,记录下,
具体表现:首次进入问题界面ok,切换其他界面后,再次进入问题界面,应用终止
堆栈信息如下:
Caused by: java.lang.IllegalArgumentException: Binary XML file line #50: Duplicate id 0x7f0c001e, tag null, or parent id 0xffffffff with another fragment forpackagename..ConversationListFragment
at android.support.v4.app.FragmentManagerImpl.onCreateView(FragmentManager.java:2422)
at android.support.v4.view.LayoutInflaterCompatHC$FactoryWrapperHC.onCreateView(LayoutInflaterCompatHC.java:44)
at android.view.LayoutInflater$FactoryMerger.onCreateView(LayoutInflater.java:168)
at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:675)
at android.view.LayoutInflater.rInflate(LayoutInflater.java:746)
at android.view.LayoutInflater.inflate(LayoutInflater.java:489)
at android.view.LayoutInflater.inflate(LayoutInflater.java:396)
at android.view.LayoutInflater.inflate(LayoutInflater.java:352)
at packagename.fragment.ChatFragment.initContentView(ChatFragment.java:103)
......
根据最后的信息,找到问题出在一个ChatFragment中,这里,先看下布局文件,如下:
fragment_conversation_list.xml,
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical"> <fragment android:id="@id/conversation_list" android:name="packagename.ConversationListFragment" android:layout_width="match_parent" android:layout_height="match_parent" /> </LinearLayout>再看ChatFragment.java中代码,如下:
@Override public View initContentView(LayoutInflater layoutInflater) { View view = layoutInflater.inflate(R.layout.fragment_conversation_list, null); ConversationListFragment fragment = (ConversationListFragment) getChildFragmentManager().findFragmentById(R.id.conversation_list); return view; }布局文件中包含一个frament,initContentView方法是在BaseFragment的OnCreateView中调用的,
那么,这里就是Fragment中包含Fragment的问题,也就是Fragment嵌套问题
好吧,在网上一通寻找,最终锁定Androd‘s documention ,还是官方的强大,定位问题准确,记得翻墙哦,这里有句如下:
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.
大致意思,不能给fragment填充包含<fragment>标签的布局。换句话,fragment对应的布局文件,不能包含<fragment>标签,fragment嵌套应当是代码动态添加。另外,用
的是getChildFragmentManager(),而不是getFragmentManager(),getChildFragmentManager是专用于主fragment管理子fragment的方法
接下来,看如何给已知fragment动态添加子fragment,避免上述开头问题的出现
fragment_conversation_list.xml,修改
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical"> <FrameLayout android:id="@+id/conversation_list_container" android:layout_width="match_parent" android:layout_height="match_parent"> </FrameLayout> </LinearLayout>原有的<fragment>标签被FrameLayout替代
ChatFragment.java,修改
@Override public View initContentView(LayoutInflater layoutInflater) { View view = layoutInflater.inflate(R.layout.fragment_conversation_list, null); ConversationListFragment fragment = (ConversationListFragment) getChildFragmentManager().findFragmentByTag("mListFragment"); if (fragment == null) { fragment = ConversationListFragment.getInstance(); getChildFragmentManager().beginTransaction().add(R.id.conversation_list_container, fragment, "mListFragment").commit(); } return view; }原有的根据id查找fragment改为根据tag查找,使用getChildFragmentManager对fragment进行动态添加
ok,改完运行,界面间任意切换,不再出现问题
当然,如果这不能解决问题,可参考:其他解决方式