在我的FragmentActivity
我使用了几个片段。当配置改变时(旋转时),系统会破坏并重新创建每个片段
我尝试使用这个重新创建的片段
mFragment = getSupportFragmentManager().findFragmentById(R.id.fragment_frame);
并将其置于新布局
getSupportFragmentManager().beginTransaction()
.replace(R.id.fragment_frame, mFragment )
.commit();
但遇到奇怪的行为:丢失了几个碎片。它们不会更多地显示在屏幕上。在他们的位置是空的。
虽然日志显示片段重新创建正常,但进一步显示片段再次被破坏,再次创建和销毁。
我为节目问题建立了更清晰,没有外壳的测试项目
以及可证明的结果(没有足够的声誉来插入图片)
Activity started picture
Activity rotated picture
A,B,C,D是fragments
正如您在配置更改后所看到的,一些片段丢失(B,D)
这里是帮助的代码(编辑:将代码推送到gitHub以便更容易尝试)
https:// github.com/nailgilaziev/TestFragmentsRetain
抱歉链接
旋转设备
后记录catMainActivity: onPause Activity
MainActivity: onStop Activity
MainActivity: onDestroy Activity
A: onDestroyview
A: onDestroy
B: onDestroyview
B: onDestroy
C: onDestroyview
C: onDestroy
D: onDestroyview
D: onDestroy
MainActivity: onCreate Activity
A: onCreate
B: onCreate
C: onCreate
D: onCreate
MainActivity: replaced
MainActivity: onStart Activity
A: onCreateView
B: onCreateView
C: onCreateView
D: onCreateView
<--before this point all fine and then strange behavior began
for the lost fragments(B,D) are performed unnecessary calls-->
B: onDestroyview
B: onDestroy
D: onDestroyview
D: onDestroy
D: onCreate
D: onCreateView
MainActivity: onResume Activity
答案 0 :(得分:7)
通过分解问题,使得有两个片段而不是四个片段,当方向发生变化时,您会看到onCreateView
在同一个片段上多次被调用。这表明同一片段被添加/创建不止一次。
基本上,当方向发生变化时,您的片段会自动重新附加,因此每次调用FragmentTransaction
时都无需执行onCreate(Bundle)
。
你应该在onCreate(Bundle)
做什么而不是......
Null检查传递到savedInstanceState
的{{1}} Bundle。 - 如果发生方向更改,则会再次调用onCreate(Bundle)
,onCreate(Bundle)
捆绑包将变为非空。 savedInstanceState
FragmentActivity
会在重新创建数据之前将其保存在onSaveInstanceState(Bundle)
中。
如果savedInstanceState
为空,请创建您的片段并通过FragmentTransaction
附加它们。否则,什么都不做。
总之,您修改后的代码应该类似于以下内容......
FragmentManager fm = getSupportFragmentManager();
if(savedInstanceState == null) {
fm.beginTransaction()
.replace(R.id.a, new A())
.replace(R.id.b, new B())
.replace(R.id.c, new C())
.replace(R.id.d, new D())
.commit();
}
else {
a = fm.findFragmentById(R.id.a);
b = fm.findFragmentById(R.id.b);
c = fm.findFragmentById(R.id.c);
d = fm.findFragmentById(R.id.d);
}
另外,请注意,savedInstanceState
onCreate(Bundle)
方法中的Fragment
捆绑包将始终为空,除非您在onSaveInstanceState(Bundle)
中保存了某些内容{1}},所以在重新创建saveInstanceState
时,Fragment
不会假设FragmentActivity
也是非空的,就像{{1}}一样。< / p>