0

fragment1当我的应用程序启动时,我在事务中将片段实例(例如,newInstance(List<Obj>)这个片段显示了一些通过静态方法传递给它的缓存数据。在onSaveInstanceState()我保存数据时,如果重新创建片段,我可以显示它。

现在假设我不重新创建片段。假设我用第二个片段替换它,比如说,fragment2(这次将事务添加到后台堆栈),执行两次屏幕旋转,然后按回。该应用程序将弹出返回堆栈并尝试fragment1再次显示,然后将尝试显示List<Obj>哪个将nullNullPointerException抛出。

我知道这是因为该fragment1实例从未被保存过,因为它不在后台堆栈中,并且在设备旋转时也没有显示。

我的问题是,在这种情况下支持屏幕旋转的最合适的方式是什么?我可以将初始事务保存在后端堆栈中,并在弹出后端堆栈之前onBackPressed()验证这一点getSupportFragmentManager().getBackStackEntryCount() >= 1(我不希望弹出初始事务,因为这fragment1是我的初始屏幕),但我认为这不是正确的方法。有任何想法吗?

4

1 回答 1

1

如果您的列表不是很大,要做的事情是将它传递给一个捆绑包onSaveInstanceState并在onRestoreInstanceState. 即使片段不在前台,这些方法仍应在销毁/重新创建时调用。但是,如果数据非常大或不可序列化或不可打包,则不能选择。

文档:

如果重新启动活动需要恢复大量数据、重新建立网络连接或执行其他密集操作,则由于配置更改而完全重新启动可能会降低用户体验。[...] 在这种情况下,您可以通过在您的活动因配置更改而重新启动时保留片段来减轻重新初始化活动的负担。此片段可以包含对您要保留的有状态对象的引用。

在这种情况下,您可能希望保留包含List<Obj>. 问题是这需要您的活动检查它可以创建的所有保留片段,onCreate以查看其中是否已经存在,并且您已经表达了对这种情况下的可维护性的担忧。

最后,您可以通过使用android:configChangesandroid 清单中的参数来声明您自己处理方向更改的意图。这将防止您的活动(及其关联的片段及其成员)在方向更改中被破坏和重新创建,而是系​​统将调用onConfigurationChanged您的活动。如果你不覆盖onConfigurationChanged,除了屏幕旋转外,方向改变不会发生任何事情。除其他原因外,Google 不鼓励这样做,因为它是代码异味。诉诸于此意味着您没有很好地处理状态更改,并且如果您的活动在用户查看其他内容时被破坏,则您的状态将无法正确保留。

编辑:

如果您的片段通过其参数包接收其数据,例如从对 的调用setArguments(),则该包“将在片段销毁和创建过程中保留。

于 2015-07-21T20:00:09.673 回答