片段在旋转时没有被破坏

我有一个以编程方式添加的片段。 然而,我发现在旋转之后,会创建一个新片段,但旧片段仍处于活动状态(虽然没有显示)我假设片段与旋转活动一起被销毁,但这不是这里的情况。 什么可能导致我的片段被保留/不被破坏? 请注意:

  1. 我没有设置setRetainInstance。
  2. 该片段未添加到活动onCreate中(稍后在点击按钮时添加)
  3. 我可以看到onDestroy在旋转时被调用
  4. 虽然添加了片段,但它会模糊添加按钮,只有在我执行“删除”时才会被删除。

创建片段的代码:

MyFragment fragment = MyFragment(); FragmentManager fragmentManager = getFragmentManager(); FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction(); fragmentTransaction.add(R.id.content_frame, fragment, "CurrentFragment"); fragmentTransaction.show(fragment).commit(); 

删除片段的代码:

 FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction(); fragmentTransaction.remove(fragment).commit(); 

更新:我无法确认这是否是问题,但片段在onCreate中注册为LocalBroadcast接收器。 它在onDestroy中未注册广播,但似乎LocalBroadcast注册阻止调用onDestroy,或者在旋转时没有调用onDestroy。 我现在在onStop中取消注册,这似乎解决了这个问题。

由于方向更改而重新启动Activity时,Android Framework会自动重新创建并添加Fragment。 您可能在Activity onCreate中添加了Fragment。 这是您在方向更改后添加其他片段的位置。

您必须检查是否已添加片段:

 Fragment f = getFragmentManager().findFragmentById(R.id.content_frame); if(f == null){ //Add it, there is no Fragment }else{ //It's already there } 

每次你添加添加片段的按钮时,都会添加一个新的片段。 如果您的容器是FrameLayout,您可能不会看到它。 尝试替换片段:

 fragmentTransaction.replace(R.id.content_frame, fragment, "CurrentFragment"); 

方法setRetainInstance(true)有另一个目的。 如果启用它,则方向更改时不会销毁Fragment实例(但其视图将被销毁)。 这意味着您可以将数据存储在Fragment的成员variables中,并且在更改方向后此数据仍然可用。

设置setRetainInstance(true)时,Fragment的生命周期略有不同。 即onCreate()onDestroy()未被调用(因为那些事件不会发生)

为什么不能用要加载的新片段替换现有片段。

试试这可能对你有帮助。

 FragmentNew mFragmentNew = new FragmentNew ();// Which you want to load That Fragment Object getFragmentManager().beginTransaction() .replace(R.id.item_detail_container, mFragmentNew) .commit(); 

您的片段可能在活动onDestroy()之前保存在Bundle对象中。 尝试在onSaveInstanceState()中处理删除片段:

 @Override protected void onSaveInstanceState(Bundle outState) { //remove here fragments super.onSaveInstanceState(outState); } 

或者你可以在onCreate()中创建Bundle null:

 @Override protected void onCreate(Bundle savedInstanceState) { savedInstanceState = null; super.onCreate(savedInstanceState); } 

我有这个问题,我解决了它只是替换这一行

 fragmentTransaction.add(R.id.content_frame, fragment, "CurrentFragment"); 

 fragmentTransaction.replace(R.id.content_frame, fragment, "CurrentFragment"); 

请享用

你只需要在第一次启动时添加一次Fragment ,就这样做:以下代码是从http://developer.android.com/reference/android/app/Fragment.html复制的,评论是我的:

 @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); // My Comment: only add when launched for the first time, it won't be null on orientation change if (savedInstanceState == null) { // During initial setup, plug in the details fragment. DetailsFragment details = new DetailsFragment(); details.setArguments(getIntent().getExtras()); getFragmentManager().beginTransaction().add(android.R.id.content, details).commit(); } }