似乎无论我是否将 retainInstance 设置为 true,当我旋转设备时,我都会得到一个现有的 fragment 。不同之处在于,如果我将它设置为 true,我会得到“test = yes!”,否则我会得到“test = no!”。单击测试按钮更改测试
后旋转设备后。也就是说,如果我保留实例,则保留成员变量。
但正如我所说,即使我不保留它,我也会从管理器那里得到一个现有的 fragment (总是在轮换时得到“重用现有的”)。在那种情况下,如果所有成员变量都丢失并重新创建 fragment 的 View ,保留了什么?获取 fragment 的现有实例有什么意义?
在 Activity 的onCreate中,
var frag = supportFragmentManager.findFragmentById(R.id.frame)
if(frag == null)
{
frag = Fragment1.newInstance("", "");
}
else
{
Log.d("sss", "Reusing exsiting");
}
val transaction = supportFragmentManager.beginTransaction()
transaction.replace(R.id.frame, frag)
transaction.commit()
在 fragment 中,
var test = "no!";
override fun onViewCreated(view: View, savedInstanceState: Bundle?)
{
super.onViewCreated(view, savedInstanceState)
Log.d("sss", "test = " + test);
testButton.setOnClickListener {
test = "yes!";
}
}
最佳答案
我花了几个小时尝试用不同的场景重现您的情况。首先,我要指出的是, fragment 的生命周期实际上非常复杂,以至于在 2018 年 Google I/O 期间,一位主要开发人员询问观众 onCreate()
方法是否 Activity
或 Fragment
的首先被调用。答案是,这取决于 SDK 版本。但他们越来越关注兼容性库,并建议开发人员使用它们在不同设备上获得通用体验,并享受新的 API 来完成处理 fragment 的工作,这对我们来说要容易得多。
在查看 AppCompatActivity 的文档时class,我意识到这种行为是他们处理 fragment 的方式。
Protected methods
void onCreate(Bundle savedInstanceState)
Perform initialization of all fragments.
void onDestroy()
Destroy all fragments.
void onPostCreate(Bundle savedInstanceState)
void onPostResume()
Dispatch onResume() to fragments.
void onSaveInstanceState(Bundle outState)
Save all appropriate fragment state.
void onStart()
Dispatch onStart() to all fragments.
void onStop()
Dispatch onStop() to all fragments.
如您所见,它们在 onSaveInstanceState()
中“保存所有适当的 fragment 状态”;这意味着状态将在 Activity
被销毁并重新创建之后恢复。所以在 onDestroy()
中,所有 fragment 都被销毁,当再次创建 Activity
时,它们也会被重新创建。为了确定,您可以在 Fragment
和 Activity
中覆盖这些方法并检查结果。如果您不检查 FragmentManager
是否已附加 fragment ,则 Fragment
的 onCreate()
方法将被调用两次,一次由您直接添加作为一个新的 Fragment
- 一次由 AppCompatActivity
本身。
关于retainInstance = true
,文档说它在配置更改期间保留成员变量,并且会导致Fragment
的生命周期略有不同。
关于android - 创建新 fragment 与轮流从经理那里获取现有 fragment 之间的区别,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50131469/