我怎么可以用setRetainInstance(true)将碎片与碎片分开,然后将它们添加到backstack?

setRetainInstance上的文档说:

这只能用于不在后面堆栈中的碎片。

所以我开始玩了。

我有一个活动添加第一个片段A

FragmentManager fm = getSupportFragmentManager(); FragmentTransaction ft = fm.beginTransaction(); ft.replace(R.id.content, new PackageFragment()); ft.commit 

然后从这个片段我运行一个方法从父Activity,它将碎片B添加到后台堆栈

 FragmentManager fm = getSupportFragmentManager(); FragmentTransaction ft = fm.beginTransaction(); ft.replace(R.id.content, new OrderFragment()); ft.addToBackStack(null); ft.commit(); 

然后我创build日志味精从onCreate,onDestroy,onSaveInstanceState,onActivityCreated …等

我尝试了这个过程的两个版本。 旋转每个碎片上的设备。

  1. 默认

一切都如预期。 onCreate,onDestroy在碎片上着火

  1. setRetainInstance(真)

一切都如预期的那样。 onCreate,onDestroy的片段不火

而所有似乎都在碎片在后台工作..所以为什么文档说我不应该使用它? 有什么情况可能会遇到麻烦?

谢谢

Solutions Collecting From Web of "我怎么可以用setRetainInstance(true)将碎片与碎片分开,然后将它们添加到backstack?"

更新回答:

有什么情况可能会遇到麻烦?

当将Fragment添加到后端堆栈并在configuration更改时将Fragment中的BundleonSaveInstanceState()传递到onCreateView()时。 调用setRetainInstance(true)将在configuration更改时将Bundle设置为null。

(我不确定一个开发人员实际上会尝试这个,因为使用setRetainInstance(true)使onSaveInstanceState()types是多余的,但我没有看到在API文档中logging的行为,所以我写了这个答案)。

如果同时addToBackStack()setRetainInstance(true) ,与仅调用addToBackStack()相比, setRetainInstance()部分更改configuration更改上的Fragment生命周期方法调用和参数值。

具体来说,在下面的testing中,查看只调用addToBackStack()和调用setRetainInstance(true)之间的差异,并查看configuration更改会发生什么:

调用addToBackStack()但不是setRetainInstance(true) ;

  • onCreate()onDestroy()被调用。
  • onSaveInstanceState()传递的包作为onCreateView()的参数被接收。

调用addToBackStack()setRetainInstance(true)

  • onCreate()onDestroy()不会被调用。 这是在API文档中提到的。
  • onCreateView()没有收到从onSaveInstanceState()传入的包。 传入的Bundle为null。

logging的方法调用和参数testing为null的testing:

Activity

 @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); MyFragment fragment; if (savedInstanceState != null) { fragment = (MyFragment) getFragmentManager().findFragmentByTag("my_fragment_tag"); } else { fragment = new MyFragment(); FragmentTransaction t = getFragmentManager().beginTransaction(); t.addToBackStack(null);//toggle this t.add(android.R.id.content, fragment, "my_fragment_tag").commit(); } } 

Fragment

 @Override public void onActivityCreated(Bundle savedInstanceState) { super.onActivityCreated(savedInstanceState); setRetainInstance(true);//toggle this } 

 @Override public void onSaveInstanceState(Bundle outState) { outState.putString("test", "value"); super.onSaveInstanceState(outState); } 

testing1:调用addToBackStack()时的片段生命周期,并且调用setRetainInstance(true)

  • onAttach()
  • 的onCreate()
  • onCreateView()
  • onActivityCreated()
  • 在onStart()
  • 的onResume()

[从纵向旋转到横向的设备]

  • 的onPause()
  • 的onSaveInstanceState()
  • 的onStop()
  • onDestroyView()
  • 的onDestroy()
  • onDetach()
  • onAttach()
  • 的onCreate()
  • 带有bundle参数的onCreateView()!= null
  • 在onStart()
  • 的onResume()

testing2&3:使用setRetainInstance(true)调用片段生命周期调用,调用addToBackStack() /不调用(相同的结果):

  • onAttach()
  • onCreateView()
  • onActivityCreated()
  • 在onStart()
  • 的onResume()

[从纵向旋转到横向的设备]

  • 的onPause()
  • 的onSaveInstanceState()
  • 的onStop()
  • onDestroyView()
  • onDetach()
  • onAttach()
  • onCreateView()与包参数== null
  • 在onStart()
  • 的onResume()