旋转时保留片段对象

问题描述:

我在Honeycomb中开发了一个应用程序,并且正在使用片段。
这是我的应用程序旋转时保留片段对象

  • 我有一个活动(说A1),并且其中有一个片段
  • 最初,这个片段保存对象中的一个片段对象说(F1)
  • 然后视用户操作可能会改成其他物体F2,F3 ....

我的问题是什么

当用户旋转活动并重新创建该设备使F1的片段对象,即使旋转之前它不是
What is the way to retain the fragment object while rotating?
我用setRetainInstance(true);但它并没有为我工作
我有在我的onCreate函数中添加片段

@Override 
public void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.main); 

    FragmentTransaction fragmentTransaction = getFragmentManager().beginTransaction(); 

    Fragment homeFragment = new Home(); 
    fragmentTransaction.add(R.id.mainFragement, homeFragment); 
    fragmentTransaction.commit(); 
} 

默认情况下,Android将保留片段对象。在您的代码中,您可以在onCreate函数中设置homeFragment。这就是为什么它总是一些homeFragmentfl什么,你在onCreate设置。

因为每当你转动时,的onCreate将执行与您的片段对象设置为第一个

所以你最简单的办法是检查savedInstanceState包是否为空或不是,并设置片段对象

@Override 
public void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 

    if(null == savedInstanceState) { 
     // set you initial fragment object 
    } 
} 
+1

我应该在的情况下我用的与处理碎片的ViewPager活动? – 2012-08-17 22:56:31

+0

@androiddeveloper祈祷。没有认真地做我的是:super.onCreate(null); – Warpzit 2012-11-09 10:53:36

+19

“默认情况下,android会保留片段对象”...不正确。除非调用'setRetainInstance(true)',否则Android将根据方向更改创建新对象。不要将此与Android自动重新连接片段混淆。它们不是同一件事。检查由S.D.报告的痕迹在[这个答案](http://*.com/a/12641575/2619107)。 – Rafa 2013-11-14 20:58:38

你需要给你的片段一个独特的标签,并检查这个片段是否已经添加到你的活动已经或没有。

public void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.main); 
    String tag = "my_fragment"; 
    FragmentManager fragmentManager = getFragmentManager(); 
    if(fragmentManager.findFragmentByTag(tag) == null) { 
     FragmentTransaction fragmentTransaction = getFragmentManager().beginTransaction(); 
     Fragment homeFragment = new Home(); 
     fragmentTransaction.add(R.id.mainFragement, homeFragment, tag); 
     fragmentTransaction.commit(); 
    } 
} 

检查savedInstanceState是否为空是不是要检查你的片段是否已经设置了安全的方式 - 它会在大多数情况下工作,但在某些情况下(例如,当设备处于低内存),安卓可能会导致您的活动中断,这可能会破坏您的应用

要在操作中看到此操作,请在设备的开发选项中勾选“不要保留活动”(该设置在Android 4.0+中可用,不确定早期版本)。当你打开一个新的活动时,你的第一个活动就会被销毁。当您返回时(通过按回),它会再次创建,并且savedInstanceState为而不是为空。但是,您的片段不再处于活动状态,您必须再次添加它。

编辑 - 显示原来的原则,但与SupportFragmentManager

public class ActivityAwesome extends AppCompatActivity 
{ 
    private final String TAG = getClass().getSimpleName(); 
    private FragmentHome mHomeFragment; 

    @Override 
    protected void onCreate(Bundle savedInstanceState) 
    { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.activity_layout); 

     FragmentManager fragmentManager = getSupportFragmentManager(); 
     Fragment fragment = fragmentManager.findFragmentByTag(TAG); 
     if(fragment == null) 
     { 
      // Create the detail fragment and add it to the activity using a fragment transaction. 
      mHomeFragment = new FragmentHome(); 
      fragmentManager.beginTransaction() 
        .add(R.id.fragment_container, mHomeFragment, TAG) 
        .commit(); 
     } 
     else 
     { 
      // get our old fragment back ! 
      mHomeFragment = (FragmentHome)fragment; 
     } 
    } 
} 

+0

虽然我以前使用过@labeeb提供的答案,但我认为检查独特的“标签”是最好的方法。 – 2015-12-15 08:30:09

+0

有趣! Google似乎需要更新他们的模板代码。 – 2016-02-12 19:08:02

我定义旋转你的设备在这之后进来,如果你要处理的片段(在这种情况下mHomeFragment)特别有用一个Fragment在活动的布局中,Fragment中的onSaveInstanceState确实被调用,但片段的onCreatView中的savedInstanceStateBundle为空。

的原因是我的Fragment没有一个XML格式的ID:

android:id="@+id/compass_fragment" ... 

使用onAttachFragment()Activity重新分配对象:

@Override 
public void onAttachFragment(Fragment fragment) { 
    if (fragment instanceof MyFragment) 
     this.myFragment = (MyFragment) fragment; 
}