如何确定从后台堆栈中恢复的碎片

一直在寻找这个问题一时无济于事:

如何确定片段正在从后台恢复? 我在FragmentActivity中使用兼容性库和一个ListFragment。 当selectListFragment内的项目时,将启动一个新的Fragment来replaceListFragment。

我注意到,当FragmentActivity被暂停时,Fragment的onSaveInstanceState被调用。 但是,当Fragment通过FragmentTransaction被放入后端堆栈时,onSaveInstanceState不会被调用,那么onCreateView和onActivityCreated的生命周期方法将被调用,并且保存为null savedInstanceState Bundle。

我这样问是因为我想在创build或恢复碎片时加载一些数据,但是当用户回来的时候不是这样。 堆栈中。

我看过如何检查片段是从一个后台堆栈恢复? 但希望增加更多的细节,希望这会煽动一个答案。

编辑:只是注意到http://developer.android.com/reference/android/app/Fragment.html#onSaveInstanceState(android.os.Bundle)说

但请注意:此方法可能在onDestroy()之前的任何时候被调用。 在很多情况下,一个片段可能大部分被拆除(比如放置在没有UI显示的后端堆栈上),但是在其拥有的活动实际上需要保存其状态之前,其状态将不会被保存。

所以onSaveInstanceState肯定是不可能的…

我认为最简单的方法是在onViewCreated()方法中做这个例子:

 if (savedInstanceState == null && !mAlreadyLoaded) { mAlreadyLoaded = true; // Do this code only first time, not after rotation or reuse fragment from backstack } 

因为当android把fragment放在backstack上时,它只会破坏它的视图,但是不会杀死实例本身,所以当从backstack中恢复fragment时,mAlreadyLoaded仍然是true。

 getSupportFragmentManager().addOnBackStackChangedListener(new OnBackStackChangedListener() { public void onBackStackChanged() { Log.i(TAG, "back stack changed "); int backCount = getSupportFragmentManager().getBackStackEntryCount(); if (backCount == 0){ // block where back has been pressed. since backstack is zero. } } }); 

使用这个addOnBackStackChangedListener。

当一个片段去反向堆栈onDestroyView()调用。 不是onDestroy()

并且当一个片段从后台堆栈onCreateView()调用。 不是onCreate()

所以添加一个boolean mIsRestoredFromBackstack来分割,并按照如下所示:

 @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); mIsRestoredFromBackstack = false; } @Override public void onResume() { super.onResume(); if(mIsRestoredFromBackstack) { // The fragment restored from backstack, do some work here! } } @Override public void onDestroyView() { super.onDestroyView(); mIsRestoredFromBackstack = true; } 

主要编辑 :2013年10月15日

前面的解释(保留在下面作为参考)在应用程序被置于后台并被带回到前台时失败。

相反,最好将当前的后台大小与创build片段并将其放入后台时的大小进行比较。


仔细看看http://developer.android.com/guide/components/fragments.html#Creating中的图2

这个图告诉你的是,当一个片断从backstack中恢复时,onCreate()不会被调用,而onCreateView()是。


所以,你可能想要做这样的事情:

 public class MyFragment extends Fragment { int mBackStackSize = 0; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); mBackStackSize = getFragmentManager().getBackStackEntryCount(); } public boolean isRestoredFromBackstack() { return mBackStackSize > getFragmentManager().getBackStackEntryCount(); } } 

如果你添加了片段到后台堆栈,经过一些操作,你可以使用fragmentTransaction.hide(fragment)来隐藏它,然后从后台堆栈中像fragmentTransaction.show(fragmentManager.findFragmentByTag(fragment.getName())); 你可以重载onHiddenChanged(boolean hidden)

 @Override public void onHiddenChanged(boolean hidden) { // TODO Auto-generated method stub super.onHiddenChanged(hidden); if (!hidden) { //fragment became visible //your code here } } 

在某些情况下,您可以使用isVisible方法来理解它是首先显示一个片段还是从后台堆栈中恢复。

 Fragment.getFragmentManager() == null 

之前添加和popup后