在 Activity 重新创建时如何确定 Fragment 恢复?

Posted

技术标签:

【中文标题】在 Activity 重新创建时如何确定 Fragment 恢复?【英文标题】:What to determine a Fragment restore upon Activity re-create? 【发布时间】:2013-03-11 11:03:44 【问题描述】:

对于有ID的Views,调用super.onSaveInstanceState(outState);时会自动保存。

对于添加到ActivityFragments,在哪些情况下会在重新创建其Activity 时重新创建(例如屏幕旋转),在哪些情况下不会?要确定什么?规则是什么?

到目前为止,我已经尝试了以下案例。但反复试验并不意味着任何规则或解决方案。

Fragments 重新存储的情况:

    正常情况:FragmentTransaction.add() 到带有 ID 的布局。 没有 UI 的片段:FragmentTransaction.add() 仅用于标记

Fragments 重新存储的情况:

    super.onSaveInstanceState(outState); 被跳过时。 在没有匹配 ID 的 UI 中恢复 Fragments。

一般规则是什么?我在文档中遗漏了什么?

提前致谢。


编辑:

根据我的理解和实验,所有动态(以编程方式)添加的Fragments 都保存在他们的Activity 调用super.onSaveInstanceState(outState) 时。

所有动态(以编程方式)添加的Fragments包括, Fragments 只有一个标签(没有 UI), Fragments 附加到 View(带有 UI), 和Fragments 一个用户界面和一个标签。 (还有其他类型吗?)

关于将带有 UI 的 Fragment 恢复到没有匹配 ID 的布局中,Fragment 确实是重新创建的。它只是无法在布局中直观地显示,并带有以下警告消息:

04-08 11:41:22.445: W/PhoneWindow(9853): Previously focused view reported id 2131165226 during save, but can't be found during restore.

一旦我们回到具有匹配 ID 的 UI,它就会正确恢复。


我仍然期待一些可靠的参考和您的意见!

【问题讨论】:

有了source codes,所有的问题都可以解决:) 【参考方案1】:

我遇到了同样的问题,你可以在这里查看:After screen rotation, findFragmentById() returns a fragment, even if there's no such ID inside the layout

http://developer.android.com/training/basics/fragments/communicating.html 的 Android 开发者文档引用了以下内容:

当配置更改导致活动托管这些 要重新启动片段,它的新实例可能会使用不同的布局 不包含与先前布局相同的片段。在这个 情况下所有先前的片段仍将被实例化并且 在新实例中运行。然而,任何不再 与视图层次结构中的标签关联的 他们的内容视图已创建并将从 isInLayout() 返回 false。 (此处的代码还显示了如何确定是否放置了片段 在容器中不再在具有该容器的布局中运行 并避免在这种情况下创建其视图层次结构。)

这意味着,我们必须检查屏幕方向而不是相信空指针检查。

【讨论】:

以上是关于在 Activity 重新创建时如何确定 Fragment 恢复?的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Android M 或更高版本中在运行时更改权限时防止重新创建 Activity

MVVM // 在 Activity 旋转时触发 ViewModel 事件(重新创建)

从通知启动时防止重新创建活动活动

3.4 重新创建 Activity

始终重新创建具有 launchMode singleTop 或 singleTask 的 Activity

Android11.5 创建和管理Fragments