Can't change container ID of fragment

在学习kotlin的过程中,使用viewpager+fragment+BottomNavigationView想实现滑动切换页面效果。

我在viewpager的onPageSelected中滑动就切换到指定页,以为是要进行fragment的add或者replace操作,然后看到各路大神纷纷推荐kotlin中优雅地添加fragment,就去跟着人家搞什么扩展函数,具体是这篇文章:

使用Kotlin优雅的添加Fragment

结果就出现这个bug了,这个意思是说不能修改fragment的容器id。

然后捏,老半天百度,没有解决。就在这时,突然看到别人的某某源码分析,然后我才静下心来分析下。哦,原来我在setAdapter设置了fragment数组以后,FragmentPagerAdapter人家自动就给你各种add事务操作了,具体我看到有这段,应该是初始化操作吧:

这里可以看到就有各种事务操作了,这其中就有添加容器id,所以我再去add或者replace就不能更改containerId了。报错原因是BackStackRecord源码里面有个方法是这么写的:
private void doAddOp(int containerViewId, Fragment fragment, @Nullable String tag, int opcmd) {
        Class fragmentClass = fragment.getClass();
        int modifiers = fragmentClass.getModifiers();
        if (fragmentClass.isAnonymousClass() || !Modifier.isPublic(modifiers) || fragmentClass.isMemberClass() && !Modifier.isStatic(modifiers)) {
            throw new IllegalStateException("Fragment " + fragmentClass.getCanonicalName() + " must be a public static class to be  properly recreated from" + " instance state.");
        } else {
            fragment.mFragmentManager = this.mManager;
            if (tag != null) {
                if (fragment.mTag != null && !tag.equals(fragment.mTag)) {
                    throw new IllegalStateException("Can't change tag of fragment " + fragment + ": was " + fragment.mTag + " now " + tag);
                }

                fragment.mTag = tag;
            }

            if (containerViewId != 0) {
                if (containerViewId == -1) {
                    throw new IllegalArgumentException("Can't add fragment " + fragment + " with tag " + tag + " to container view with no id");
                }

                if (fragment.mFragmentId != 0 && fragment.mFragmentId != containerViewId) {
                    throw new IllegalStateException("Can't change container ID of fragment " + fragment + ": was " + fragment.mFragmentId + " now " + containerViewId);
                }

                fragment.mContainerId = fragment.mFragmentId = containerViewId;
            }

            this.addOp(new BackStackRecord.Op(opcmd, fragment));
        }
    }

关于BackStackRecord这个类,可以看:Android进阶——Fragment详解之操作原理(三)

这个方法是执行添加fragment的操作,这里在adapter的初始化方法中已经把container的id传过去了,但是我可能脑子不知道短路还是咋的,又去布局里面放了个FrameLayout把viewPager给放进去了,把FrameLayout当作容器,人家本来是以ViewPager为容器的,所以当然第二次的时候容器id不一样了,就报错了。

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值