這個問題,是在使用其他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,改完運行,界面間任意切換,不再出現問題
當然,如果這不能解決問題,可參考:其他解決方式