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事务操作了,具体我看到有这段,应该是初始化操作吧:

Can't change container ID of fragment_第1张图片

这里可以看到就有各种事务操作了,这其中就有添加容器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不一样了,就报错了。

你可能感兴趣的:(安卓开发,errors)