gpt4 book ai didi

android - fragment 实例被保留但子 fragment 没有重新附加

转载 作者:IT老高 更新时间:2023-10-28 13:45:44 24 4
gpt4 key购买 nike

更新:接受的答案指向解释(错误)的解决方法,但也可以在下面查看我的基于 Kotlin 的解决方法作为答案。

这段代码在 Kotlin 中,但我认为这是一个基本的 android fragment 生命周期问题。

我有一个 fragment ,其中包含对另一个“子 fragment ”的引用

这基本上是我正在做的事情:

  1. 我有一个将 retainInstance 设置为 true 的主 fragment
  2. 我在主 fragment 中有一个字段,它将保存对子 fragment 的引用,最初该字段为空
  3. 在主 fragment 的onCreateView中,我检查子 fragment 字段是否为空,如果是,我创建一个子 fragment 的实例并将其分配给该字段
  4. 最后我将子 fragment 添加到主 fragment 布局中的容器中。
  5. 如果该字段不为空,即由于配置更改,我们在onCreateView中,我不会重新创建子 fragment ,我只是尝试将其添加到容器中。

当设备旋转时,我确实观察到被调用的子 fragment 的 onPaused()onDestroyView() 方法,但我没有看到任何生命周期方法在重新创建主 fragment View 时,在将保留的对子 fragment 的引用添加到 child_container 的过程中在子 fragment 上被调用。

最终影响是我在主 fragment 中看不到子 fragment View 。如果我注释掉 if (subfragment == null) 并且每次只创建一个新的子 fragment ,我确实会在 View 中看到该子 fragment 。

更新

下面的答案确实指出了一个错误,其中 childFragmentManager 不会在配置更改时保留。这最终会破坏我的预期用途,即在旋转后保留 backstack,但我认为我看到的是不同的东西。

我在 Activity onWindowFocusChanged 方法中添加了代码,当应用程序首次启动时,我看到了这样的内容:

activity is in view
fm = FragmentManager{b13b9b18 in Tab1Fragment{b13b2b98}}
tab 1 fragments = [DefaultSubfragment{b13bb610 #0 id=0x7f0c0078}]

然后在旋转之后:

activity is in view
fm = FragmentManager{b13f9c30 in Tab1Fragment{b13b2b98}}
tab 1 fragments = null

这里的 fm 是 childFragmentManager,如您所见,我们仍然有相同的 Tab1Fragment 实例,但它有一个新的 childFragmentManager,我认为这是不需要的,并且由于下面的答案中报告的错误。问题是我确实将子 fragment 添加到了这个new childFragmentManger。因此,似乎事务永远不会使用对保留的 fragment 的引用执行,但如果我创建一个全新的 fragment ,它就会完成。 (我确实尝试在新的 childFragmentManager 上调用 executePendingTransactions)


class Tab1Fragment: Fragment() {

var subfragment: DefaultSubfragment? = null

override fun onCreateView(inflater: LayoutInflater?, container: ViewGroup?,
savedInstanceState: Bundle?): View? {
val rootView = inflater!!.inflate(R.layout.fragment_main, container, false)
if (subfragment == null ) {
subfragment = DefaultSubfragment()
subfragment!!.sectionLabel = "label 1"
subfragment!!.buttonText = "button 1"
}
addRootContentToContainer(R.id.child_container, content = subfragment!!)

return rootView
}

override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
retainInstance = true
}

inline fun Fragment.addRootContentToContainer(containerId: Int, content: Fragment) {
val transaction = childFragmentManager.beginTransaction()
transaction.replace(containerId, content)
transaction.commit()
}

最佳答案

您的问题与此处描述的问题相似:

https://code.google.com/p/android/issues/detail?id=74222

很遗憾,这个问题可能不会被 google 解决。

为 UI 或嵌套 fragment 使用保留 fragment 不是一个好主意 - 建议使用它们来代替 onRetainNonConfigurationInstance,即。对于大型集合/数据结构。此外,您会发现 Loaders 比保留的 Fragment 更好,它们在配置更改期间也会保留。

顺便说一句。我发现保留的 fragment 更像是一种 hack——比如使用 android:configChanges 来“修复”由屏幕旋转引起的问题。这一切都有效,直到用户按下主屏幕并且 android 决定终止您的应用程序进程。一旦用户想要返回您的应用程序 - 您保留的 fragment 将被销毁 - 您仍然需要重新创建它。因此,如果您的资源随时可能被破坏,编写所有代码总是更好。

关于android - fragment 实例被保留但子 fragment 没有重新附加,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34569492/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com