旋转时保留碎片物体

我在Honeycomb开发了一个应用程序,我正在使用碎片。
这是我的应用程序

  • 我有一个活动(说A1),并在那里有一个片段
  • 最初这个片段持有对象一个片段对象说(F1)
  • 然后根据用户的操作,它可能会改变到其他对象F2,F3 ….

我的问题是什么

当用户旋转设备时,活动被重新创build,并且使得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 。 这就是为什么它总是一些homeFragment或者你在homeFragment什么。

因为每当你旋转,onCreate将执行和设置你的片段对象的第一个

因此,简单的解决scheme是检查savedInstanceState包是否为null,并设置片段对象

 @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); if(null == savedInstanceState) { // set you initial fragment object } } 

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

 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可能会杀死您的活动,这可能打破你的申请。

要看到这一点,请在设备的开发选项中勾选“不要保留活动”(该设置在Android 4.0+中可用,不确定早期版本)。 当你打开一个新的活动,你的第一个活动被破坏。 当你回到它(通过按回),它被重新创build,并且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; } } } 

如果您想要在旋转设备之后操作片段(在这种情况下是mHomeFragment ),这会特别有用

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

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

我在activity的布局中定义了一个FragmentFragment中的onSaveInstanceState确实被调用,但是fragment的onCreatViewsavedInstanceState Bundle为null。

原因是我的Fragment在XML中没有ID:

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