如何确定从后台堆栈中恢复的碎片
一直在寻找这个问题一时无济于事:
如何确定片段正在从后台恢复? 我在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后