一个Activity,多个Fragments和setRetainInstance

时间:2013-01-17 13:31:56

标签: android android-fragments

在我的应用中,我正在使用一个活动和两个片段。该应用程序使用带有容器的布局,以便通过事务添加片段。第一个片段包含listview,另一个片段包含listview项的详细视图。 两个片段都使用setRetainInstance(true)。片段通过替换事务添加,并设置addToBackStack(null)。 listfragment包含一个实例变量,它包含列表的一些信息。现在我正在更改细节并按回来,实例变量为null。我读了关于setRetainInstance和addToBackStack并删除了addToBackStack,但即使这样,实例变量也是null。

有谁知道我可能做错了什么?

的问候, 托马斯

1 个答案:

答案 0 :(得分:4)

setRetainInstance(true)会告诉FragmentManager在包含Activity由于某种原因被杀死并重建时保留片段。在添加或替换事务后,它不保证Fragment实例会保留。听起来你的适配器正在被垃圾收集,而你却没有创建一个新适配器。

更普遍的简单解决方案是让无视Fragment保留您的ListAdapter。执行此操作的方法是创建Fragment,将retain instance设置为true,并在方法null中返回onCreateView()。要添加它,只需通过addFragment(Fragment, String)调用FragmentTransaction即可。您永远不会删除或替换它,因此它将永远留在内存中应用程序的长度。屏幕旋转不会杀死它。

每当您创建ListFragment时,在onCreateView()中获取FragmentManager并使用方法findFragmentById()FindFragmentByTag()从内存中检索您保留的片段。然后从该片段中获取适配器并将其设置为列表的适配器。

public class ViewlessFragment extends Fragment {

   public final static string TAG = "ViewlessFragment";

   private ListAdapter mAdapter;

   @Override
   public ViewlessFragment() {
      mAdapter = createAdater();
      setRetainInstance(true);
   }

   @Override
   public void onCreateView (LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
      return null;
   }

   public ListAdapter getAdapter() {
      return mAdapter;
   }
}

public class MyListFragment extends ListFragment {

   final public static String TAG = "MyListFragment";

   @Override
   public void onCreateView (LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
      final View returnView = getMyView();
      final ViewlessFragment adapterFragment = (ViewlessFragment) getFragmentManager().findFragmentByTag(ViewlessFragment.TAG);
      setListAdapter(ViewlessFragment.getAdapter());
      return returnView;
   }
}

public class MainActivity extends FragmentActivity {

   @Override
   public void onCreate(Bundle icicle) {
      // ... setup code...
      final FragmentManager fm = getSupportFragmentManager();
      final FragmentTransaction ft = fm.beginTransaction();
      ViewlessFragment adapterFragment = fm.findFragmentByTag(ViewlessFragment.TAG);
      if(adapterFragment == null) {
         ft.add(new ViewlessFragment(), ViewlessFragment.TAG);
      }
      ft.add(R.id.fragmentContainer, new MyListFragment(), MyListFragment.TAG);
      ft.commit();
   }
}