Android IllegalStateException:已添加片段(仅当启动时调用onConfigChanged时)
只有在启动应用程序并在启动阶段立即更改方向时,才会发生此错误。调用onCreate,然后调用onResume,然后调用onConfigurationChanged,我遇到了这个错误。如果我启动应用程序,等待一秒钟,然后改变方向,一切都会完美无瑕 创建FragmentPagerAdapter的位置。这是在主活动的onCreate中Android IllegalStateException:已添加片段(仅当启动时调用onConfigChanged时),android,android-fragments,Android,Android Fragments,只有在启动应用程序并在启动阶段立即更改方向时,才会发生此错误。调用onCreate,然后调用onResume,然后调用onConfigurationChanged,我遇到了这个错误。如果我启动应用程序,等待一秒钟,然后改变方向,一切都会完美无瑕 创建FragmentPagerAdapter的位置。这是在主活动的onCreate中 mAdapter = new TabPagerAdapter(getFragmentManager()); viewPager.setOffscreenPageLi
mAdapter = new TabPagerAdapter(getFragmentManager());
viewPager.setOffscreenPageLimit(25); //I want those fragments to not be destroyed
viewPager.setAdapter(mAdapter);
displayFragment = new DisplayFragment();
然后创建displayFragment。这也在主活动的onCreate中
mAdapter = new TabPagerAdapter(getFragmentManager());
viewPager.setOffscreenPageLimit(25); //I want those fragments to not be destroyed
viewPager.setAdapter(mAdapter);
displayFragment = new DisplayFragment();
在FragmentPagerAdapter中,getItemPosition(对象项)为displayFragment返回0,getItem(int index)为索引0返回对displayFragment的引用
这是OnConfiguration Changed中的相关代码
if (newConfig.orientation == Configuration.ORIENTATION_LANDSCAPE) {
this.getFragmentManager()
.beginTransaction()
.detach(displayFragment)
.attach(displayFragment)
.commitAllowingStateLoss();
lastOrientation = Configuration.ORIENTATION_PORTRAIT;
//this.mAdapter.notifyDataSetChanged();
lastOrientation = Configuration.ORIENTATION_LANDSCAPE;
//this.mAdapter.notifyDataSetChanged();
}
else if (newConfig.orientation == Configuration.ORIENTATION_PORTRAIT) {
this.getFragmentManager()
.beginTransaction()
.detach(displayFragment)
.attach(displayFragment)
.commitAllowingStateLoss();
lastOrientation = Configuration.ORIENTATION_PORTRAIT;
}
和堆栈跟踪
java.lang.IllegalStateException: Fragment already added: DisplayFragment{42b66cd0 #0 id=0x7f0a0001 android:switcher:2131361793:0}
at android.app.FragmentManagerImpl.addFragment(FragmentManager.java:1133)
at android.app.BackStackRecord.run(BackStackRecord.java:618)
at android.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:1447)
at android.app.FragmentManagerImpl.executePendingTransactions(FragmentManager.java:479)
at android.support.v13.app.FragmentPagerAdapter.finishUpdate(FragmentPagerAdapter.java:145)
at android.support.v4.view.ViewPager.populate(ViewPager.java:1068)
at android.support.v4.view.ViewPager.populate(ViewPager.java:914)
at android.support.v4.view.ViewPager.onMeasure(ViewPager.java:1436)
at android.view.View.measure(View.java:17387)
at android.widget.RelativeLayout.measureChildHorizontal(RelativeLayout.java:719)
at android.widget.RelativeLayout.onMeasure(RelativeLayout.java:455)
at android.view.View.measure(View.java:17387)
at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5352)
at android.widget.FrameLayout.onMeasure(FrameLayout.java:310)
at android.view.View.measure(View.java:17387)
at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5352)
at com.android.internal.widget.ActionBarOverlayLayout.onMeasure(ActionBarOverlayLayout.java:391)
at android.view.View.measure(View.java:17387)
at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5352)
at android.widget.FrameLayout.onMeasure(FrameLayout.java:310)
at com.android.internal.policy.impl.PhoneWindow$DecorView.onMeasure(PhoneWindow.java:2533)
at android.view.View.measure(View.java:17387)
at android.view.ViewRootImpl.performMeasure(ViewRootImpl.java:2211)
at android.view.ViewRootImpl.measureHierarchy(ViewRootImpl.java:1350)
at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:1547)
at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1234)
at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:6465)
at android.view.Choreographer$CallbackRecord.run(Choreographer.java:803)
at android.view.Choreographer.doCallbacks(Choreographer.java:603)
at android.view.Choreographer.doFrame(Choreographer.java:573)
at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:789)
at android.os.Handler.handleCallback(Handler.java:733)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:157)
at android.app.ActivityThread.main(ActivityThread.java:5356)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:515)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1265)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1081)
at dalvik.system.NativeStart.main(Native Method)
我现在尝试分别提交每个事务,但错误仍然存在
this.getFragmentManager()
.beginTransaction()
.detach(displayFragment)
.commit();
this.getFragmentManager()
.beginTransaction()
.attach(displayFragment)
.commit();
任何指点都将不胜感激。谢谢。您不应该先拆下
然后再附加。
第一,因为它不会有任何影响(它在同一个事务中)。
其次,因为您可以在添加片段之前简单地检查片段是否已经添加。(无论是findFragmentByTag
将返回null,还是displayFragment.isAdded()
将返回相应的值)。看起来我找到了一些有效的方法。在OnConfiguration Changed中,如果我检查displayFragment的isResumed状态,我可以确定是否应该分离/连接它。如果在启动时旋转,则不会再发生崩溃。这将导致在不重新创建整个片段的情况下重新创建片段视图
if(displayFragment.isResumed()) {
this.getFragmentManager()
.beginTransaction()
.detach(displayFragment)
.attach(displayFragment)
.commit();
}
在DisplayFragment创建中添加片段DisplayFragment
More上下文的部分也发布所有代码。发生在哪里,哪个方法,等等。好的,还有其他的吗?首先,您应该通过调用newdisplayfragment()
直接创建片段。其次,您似乎每次都在活动的onCreate中创建一个新片段,对吗?我想我应该澄清一下。我需要强迫那个碎片毁灭,然后重建它的视图。我主要是一个iOS开发者,所以安卓对我来说是相当陌生的。这是我发现的唯一一种在不完全破坏片段的情况下使片段重新创建其视图的方法。有更好的方法吗?所以在重新附加片段之前必须提交第一个事务(分离)。我没有发现正确的错误。在这里,您应该调用remove
/add
方法如果我使用remove,整个片段将被销毁,当我调用add/show时,不会显示任何内容。理想情况下,我只想使用这个特定片段为横向布局扩展一个不同的XML。使用我最初的方法,片段并没有被完全销毁,只是它的视图。然后当它被重新连接时,onCreateView被调用,这样我就可以膨胀正确的xml。这种方法非常有效,除非您在启动应用程序时旋转设备,以便idk(如果是FragmentManager中的竞争条件)或其他情况。此片段是通过XML还是通过您的活动以编程方式添加的?我看不到它是在哪里创建/添加的