Duplicate id xxx, tag null, or parent id xxx with another fragment for xxxFragment

這個問題,是在使用其他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,改完運行,界面間任意切換,不再出現問題

當然,如果這不能解決問題,可參考:其他解決方式

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章