【问题标题】:How should I add my initial fragment while supporting screen rotations?在支持屏幕旋转的同时,我应该如何添加我的初始片段?
【发布时间】:2015-07-20 23:32:19
【问题描述】:

当我的应用程序启动时,我会动态地将片段实例(例如,fragment1)添加到未添加到后台堆栈的事务中的内容布局中。该片段显示了一些通过newInstance(List<Obj>) 静态方法传递给它的缓存数据。在onSaveInstanceState() 中,我保存数据,以便在重新创建片段时显示它。

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

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

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

【问题讨论】:

  • 您是否在onResume 中初始化/重新初始化?我希望它能处理这种情况,但我还没有测试过。
  • 这种情况下onResume我觉得没有什么特殊情况需要处理。
  • 我的意思是,你能在onResume 中重新初始化List<Obj> 吗?它应该在片段返回到前台时调用。
  • 我宁愿不要。这样做对我来说听起来不太容易维护。如果我的应用程序的初始片段可以是多个不同的片段类,或者如果我决定添加其他片段而不将事务保存到后台堆栈,则我必须在 onResume 上进行多次重新初始化。
  • 等等。抱歉,我在考虑活动的onResume。我可以在片段的onResume 上做到这一点,但据我了解,问题不止于此。 fragment1 实例正在重新创建(它在轮换期间被销毁)并且没有对原始 List<Obj> 数据的引用。

标签: android android-fragments fragment-backstack fragmentmanager


【解决方案1】:

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

来自docs:

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

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

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

编辑:

如果您的片段通过其参数包接收其数据,例如来自对 setArguments() 的调用,则该包“will be retained across fragment destroy and creation.”

【讨论】:

  • 我发现不需要将事务添加到后台堆栈。如果我将数据保存在片段的参数包中,它将在破坏和重新创建中持久保存(Fragment.getArguments() 的文档实际上提到了这一点)。如果您在回答中提到这个特定的解决方案,我很乐意接受它以感谢您的努力。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-10-01
  • 2012-01-04
  • 1970-01-01
相关资源
最近更新 更多