ILJMALL project过程中遇到Fragment嵌套问题:IllegalArgumentException: Binary XML file line #23: Duplicate id

  • 出现场景:当点击“分类”再返回“首页”时,发生error退出

  • BUG描述:Caused by: java.lang.IllegalArgumentException: Binary XML file line #23: Duplicate id 0x7f0d0054, tag null, or parent id 0xffffffff with another fragment for com.example.sxq123.iljmall.FragmentCatagorySpace
  • //framgment_home.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical" android:layout_width="match_parent"
    android:layout_height="match_parent">
    <ScrollView
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:layout_weight="1">
        <LinearLayout
            android:orientation="vertical"
            android:layout_width="match_parent"
            android:layout_height="wrap_content">

            <TextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text = "@string/home"/>

<fragment
    android:id = "@+id/fragment_space"
    android:name = "com.example.sxq123.iljmall.FragmentCatagorySpace"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"/>

</LinearLayout>
</ScrollView>
</LinearLayout>
  • //FragmentHome.java
public class FragmentHome extends Fragment {

    private View view;
    FragmentCatagorySpace fragmentCatagorySpace ;

    @Override
    public View onCreateView(LayoutInflater inflater , ViewGroup container , Bundle savedInsataceState){
        view = inflater.inflate(R.layout.fragment_home, null);
        Log.d(this.getClass().getName(),"  onCreateView() Begin");
        initChildFragment();

        return view;
    }
    private void initChildFragment(){
        Log.d("-------------------","init space ");
        fragmentCatagorySpace = (FragmentCatagorySpace)getChildFragmentManager().findFragmentById(R.id.fragment_space);
        if(fragmentCatagorySpace != null){
            Log.d("----------------","init space success and no null");
        }
    }
}
  • 问题原因

http://www.tuicool.com/articles/FNVN3i

  activity中不同的frament之间项目替换的时候,FragmentManager只会remove和add这些frament,

然而这些frament里面自己加载的frament(这里就是我们的FragmentCatagorySpace)是没有被remove. 很显然这是一个缺陷!

因为后一个frament(FragmentCatagorySpace)很明显是依赖与他的父frament的,应该同时递归的remove.

  那么如何解决这个问题呢!很显然就是在不用这个frament(FragmentHome)的时候把他里面加载的frament给remove掉!

这个操作在Fragment的重新onCreateView() inflate layout之前remove掉就可以解决问题了!

比如将remove的事务放在父Fragment的onDestroyView()之中执行

  • 修正后的代码
public class FragmentHome extends Fragment {

    private View view;
    FragmentCatagorySpace fragmentCatagorySpace ;

    @Override
    public View onCreateView(LayoutInflater inflater , ViewGroup container , Bundle savedInsataceState){
        view = inflater.inflate(R.layout.fragment_home, null);
        Log.d(this.getClass().getName(),"  onCreateView() Begin");
        initChildFragment();

        return view;
    }
@Override
public void onDestroyView(){
    super.onDestroyView();
    if(fragmentCatagorySpace != null){
        Log.d("-------------------", "space no null");
        FragmentManager fragmentManager = getFragmentManager();
        if(fragmentManager != null && !fragmentManager.isDestroyed()){
            final FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction ();
            if(fragmentTransaction != null){
                fragmentTransaction.remove(fragmentCatagorySpace).commit();
                //commit()和commitAllowingStateLoss()都是先发送到主线程任务队列中, 当主线程准备好了再执行,异步。
                // //如果没有在inflate之前执行remove child fragmetn 的transaction,将会发生duplicate id 的exception !!!
//                fragmentTransaction.commit();//可以放在onCreateView中执行commit(),但偶尔会发生onSaveInstanceState()之后不能执行commit()的冲突
                fragmentTransaction.commitAllowingStateLoss();
                //立即执行任务队列中的transaction, 不异步 !!!!!!!!!!!!!!!重点!!!!!!!!!!!!!!!!!!!!
//防止remove事务被加到主线程任务队列中,那这样异步的话可能这些事物直到父Fragment重新执行onCreateView()
//之前都没有执行完,同样会发生duplicate id 的异常
//如果这些remove 的食物放在父Fragment的onSaveInstanceState()中执行, 由于onSaveInstanceState()调用并不
//是每一个Fragment生命周期都会被调用(????),所以偶尔也会发生duplicate id  的异常
 fragmentManager.executePendingTransactions();
                Log.d("------------------","  space destroy");
            }
        }
    }
}
    private void initChildFragment(){
        Log.d("-------------------","init space ");
        fragmentCatagorySpace = (FragmentCatagorySpace)getChildFragmentManager().findFragmentById(R.id.fragment_space);
        if(fragmentCatagorySpace != null){
            Log.d("----------------","init space success and no null");
        }
    }
}
时间: 2024-11-08 12:09:32

ILJMALL project过程中遇到Fragment嵌套问题:IllegalArgumentException: Binary XML file line #23: Duplicate id的相关文章

Binary XML file line #7: Error inflating class fragment

这几天一直在学习碎片,想自己写一个相关的程序试试,没想到刚写一点就出了问题. 在加载主布局文件activity_main.xml时候,出现错误 06-12 13:11:12.873: E/AndroidRuntime(2022): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.gentleni.demo_grideview_002/com.gentleni.demo_grideview_002.Mai

Android - Binary XML file line #8: Error inflating class fragment

Error: threadid=1: thread exiting with uncaught exception (group=0x415c5940) FATAL EXCEPTION: main java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.wifidirectdemo/com.example.wifidirectdemo.MainActivity}: android.view.In

Binary XML file line #114: Error inflating class fragment

1.fragmentactivity 继承自activity,用来解决android3.0 之前没有fragment的api,所以在使用的时候需要导入support包,同时继承fragmentActivity,这样在activity中就能嵌入fragment来实现你想要的布局效果. 2.当然3.0之后你就可以直接继承自Activity,并且在其中嵌入使用fragment了. 3.获得Manager的方式也不同 3.0以下:getSupportFragmentManager() 3.0以上:get

【Android开发实践】android.view.InflateException: Binary XML file line #12: Error inflating class fragment问题解决

一般出现的原因是fragment引入的包错了,应该是import android.app.ListFragment;而不是import android.support.v4.app.ListFragment;

cocoapod安装过程中Bug

在cocoapod安装过程中遇到: diff: /../Podfile.lock: No such file or directory diff: /Manifest.lock: No such file or directory error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation. 解决: 删除pod.重新pod inst

activity 嵌套一级fragment,一级fragment嵌套二级fragment,在一级fragment中刷新二级fragment中的UI

今天遇到挺纠结的问题,由于产品设计的问题,技术上涉及到activity 嵌套一级fragment,一级fragment嵌套二级fragment,在一级fragment中刷新二级fragment中的UI. 其中一级fragment中有顶部搜索栏,搜索栏下面有viewpager+fragment的布局,搜索栏输入内容后要更新子当前页面的fragment的搜索方法,并刷新UI. adapter: private class OrderManagerFragmentPagerAdapter extend

Bulid过程中中遇到的问题UnityEditor.BuildPlayerWindow+BuildMethodException: &#39;&#39; is an incorrect path for a scene file. BuildPlayer expects paths relative to the project folder.

今天,在Bulid的过程中,遇到了一个错误“ UnityEditor.BuildPlayerWindow+BuildMethodException: '' is an incorrect path for a scene file. BuildPlayer expects paths relative to the project folder. ",大概意思就是Scenes引用的路径不对,一直以为是自己的Scenes有错,所以重新创建了一个试一下,没有任何卵用,还是一样的错.Google了一下

在Fragment中加一个嵌套了ListView的ScrollView(一)

首先介绍一下这个程序的功能: 1.顶部有两个可以切换Fragment的Button 2.在其中一个Fragment中里有个ScrollView,ScrollView中有ViewFlipper,ListView.(另一个Fragment中就随意了) 随着listView的滚动,ViewFlipper中的内容也会滚动. 3.两个布局(主布局,一个Fragment的布局(另一个没写,其实都一样)),一个Fragment,一个主Activity,重写ListView(不重写的话,不会随着ViewFlip

Fragment嵌套带来的坑--页面点击无反应(顺带ViewPager之 FragmentPagerAdapter简单分析)

接手别人的老项目.新版本测试提出一个bug: 点击Home最小化的应用->系统设置界面 改变字体后->点击进入应用->3个由viewpager 的fragmentadapter管理的 tab页面点击都没反应. 这是一个比较蛋疼的bug,猜想了很多原因,都不对. 项目的结构是 activity 内有mainfragment,mainfragment又 包含viewpager,viewpager 使用FragmentPagerAdapter 管理3个页面.所以是 activity套2层fra