解决java.lang.IllegalStateException: Fragment already added:Fragment already added问题

遇到这个问题的时候查了很多类似的回答,大多数偏向讨论DialogFragment.show()内部调用了FragmentTransaction.add()方法,所以调用DialogFragment.show()方法blabla的东西,再就是说是activity_main.xml的布局属性问题。就我个人而言,断点debug了好几处也没有多大卵用。

事实上,发现是在切换页面的时候出现了逻辑问题(嗯,我就是个渣渣)

我首先定义了一个全局变量


private BaseFragment temp;

然后在设置底部RadioButton监听器的时候用内部类实现OnCheckedChangeListener


    private class MyOnCheckedChangeListener implements RadioGroup.OnCheckedChangeListener {
        @Override
        public void onCheckedChanged(RadioGroup radioGroup, @IdRes int i) {
            switch (i)
            {
                case R.id.bt_commonpage:
                    position=0;
                    break;
                case R.id.bt_message:
                    position=1;
                    break;
                case R.id.bt_publish:
                    position=2;
                    break;
                case R.id.bt_trolley:
                    position=3;
                    break;
                case R.id.bt_selfcenter:
                    position=4;
                    break;
                default:
                    position=0;
                    break;
            }
            //将所有的fragment封装在了一个ArrayList<BaseFragment>里面,通过下标找对应的fragment
            BaseFragment base=getBaseFragment(position);
            //切换页面
            switchFragment(temp,base);
        }
    }

 
最后最重要的地方在调用swichFragment(temp,base)方法

private void switchFragment(BaseFragment temp, BaseFragment to) {
        //若切换前后界面不相同则进行切换
        if(temp!=to)
        {
            FragmentManager fm=getSupportFragmentManager();
            //开启事务
            FragmentTransaction transaction = fm.beginTransaction();
            if(!to.isAdded())
            //如果要显示的页面没有被添加过
            {
                if(temp!=null)
                {
                    transaction.hide(temp);
                }
                if(to!=null)
                {
                    //如果to页面不为空,则添加到FrameLayout中
                    transaction.add(R.id.fl_center,to).commit();
                }
            }
            else
            {
                if(temp!=null)
                {
                    transaction.hide(temp);
                }
                if(to!=null)
                {
                    //如果to页面不为空,则直接显示
                    transaction.show(to).commit();
                }
            }
            temp=to;
        }
    }
显而易见,我犯了个最zz的问题,那就是把switchFragment的变量列表里的BaseFragment名字起得和我全局变量一样。
我们只需要最后一行中的temp
temp=to;
//把这次切换后的页面保存到temp里,下一次就可以用temp和要显示的页面相比较
因此,修改如下:
 
 
 
    private void switchFragment(BaseFragment from, BaseFragment to) {
        //若切换前后界面不相同则进行切换
        if(from!=to)
        {
            FragmentManager fm=getSupportFragmentManager();
            //开启事务
            FragmentTransaction transaction = fm.beginTransaction();
            if(!to.isAdded())
            //如果要显示的页面没有被添加过
            {
                if(temp!=null)
                {
                    transaction.hide(from);
                }
                if(to!=null)
                {
                    //如果to页面不为空,则添加到FrameLayout中
                    transaction.add(R.id.fl_center,to).commit();
                }
            }
            else
            {
                if(temp!=null)
                {
                    transaction.hide(from);
                }
                if(to!=null)
                {
                    //如果to页面不为空,则直接显示
                    transaction.show(to).commit();
                }
            }
            temp=to;
        }
    }


 
哦对了,为了避免我之前说的getSupportFragmentManager在FragmentActivity和DialogFragment导包会产生的一些歧义,可以让整个类继承FragmentActivity类。
 
 
 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值