如何添加 Fragment 使其在 Activity 重新创建时不被保留?

How do add Fragment so that it is not retained across Activity re-creation?

我正在动态添加和删除视图 to/from 我的 Activity。这些视图中的每一个都被分配了一个 id 并充当特定片段的容器。我使用条件逻辑向这些视图中的每一个添加一个片段,如下所示:

if (supportFragmentManager.findFragmentById(R.id.someView) == null) {
    supportFragmentManager.beginTransaction()
        .add(R.id.someView, SomeFragment())
        .commit()
}

此条件逻辑可确保给定的视图在 Activity 的生命周期内仅添加一次片段。

此逻辑工作正常,除非重新创建 Activity(例如由于配置更改)。重新创建 Activity 时,不会自动重新创建视图,但片段似乎在重新创建后仍然存在。 (我看到碎片在游戏中幸存下来,因为 supportFragmentManager.findFragmentById(id:) 调用 return 一个非空碎片。)

我发现,如果我在 Activity.onCreate(savedInstanceState:) 方法中将视图重新添加到我的 Activity,则保留的片段会重新附加到视图,一切都很好。但是,如果我延迟将视图添加到 Activity 生命周期的稍后时间点,则片段不会重新附加到视图(并且视图显示为空白)。

最终,当 savedInstanceState 为非空时,这会导致我的 Activity.onCreate(savedInstanceState:) 方法中的逻辑混乱以解决此问题。要么我必须重新添加视图,因为它们在 Activity 被销毁时(我更愿意在 Activity 的其他地方这样做),或者我必须调用 FragmentTransaction.remove(fragment:) 来删除在游戏中幸存下来的每个片段。

有没有办法将片段添加到 Activity,这样片段就不会在 Activity 游戏中存活下来?我在 Fragment.setRetainInstance(retain:) 方法的弃用通知中看到指导是:“与其保留 Fragment 本身,不如使用非保留 Fragment 并在附加到该 Fragment 的 ViewModel 中保留保留状态。”但是,本指南没有给出任何关于如何定义非保留片段的说明。

这个答案有几个维度。

首先,我在 FragmentManager or FragmentTransaction classes which offer a means of creating a non-retained Fragment. The documentation in the deprecated Fragment.setRetainInstance(retain:) 方法中找不到任何文档或任何方法说要使用“非保留片段”,但我找不到任何解释这意味着什么的地方。

其次,此问题的解决方法是删除包含 Activity 的 onCreate(savedInstanceState:) 方法中保留的 Fragment,以便可以重新创建有问题的 Fragment 并将其附加到它的包含视图中后面的生命周期方法,如下:

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.some_activity)

    supportFragmentManager.findFragmentById(R.id.someView)?.let {
        supportFragmentManager.beginTransaction().remove(it).commit()
    }
}