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,改完运行,界面间任意切换,不再出现问题

当然,如果这不能解决问题,可参考:其他解决方式

猜你喜欢

转载自blog.csdn.net/rockykou/article/details/53312342