Как определить фрагмент, восстановленный из backstack
некоторое время искали эту проблему безрезультатно:
Как определить, что фрагмент восстанавливается из backstack? Я использую библиотеку совместимости и ListFragment внутри FragmentActivity. При выборе элемента внутри ListFragment запускается новый фрагмент для замены ListFragment.
Я заметил, что когда FragmentActivity приостанавливается, данные метода onsaveinstance фрагмент называется. Но когда фрагмент помещается в задний стек через FragmentTransaction, данные метода onsaveinstance не дозвонились, то методы жизненного цикла onCreateView и onActivityCreated вызывается с null пакет savedInstanceState.
Я спрашиваю это, потому что я хочу загрузить некоторые данные, когда фрагмент создан или восстановлен, но не так, когда пользователь возвращается через. backstack.
Я посмотрел на Как проверить, был ли восстановлен фрагмент из backstack? но хочу добавить больше деталей в надежде, что это спровоцирует ответ.
изменить: просто заметил http://developer.android.com/reference/android/app/Fragment.html#onSaveInstanceState(android.os.Bundle) говорит
Примечание однако: этот метод может быть вызван в любое время до onDestroy(). Существует много ситуаций, когда фрагмент может быть в основном снесен (например, когда он помещен в задний стек без отображения пользовательского интерфейса), но его состояние не будет сохранено, пока его собственная активность фактически не должна сохранить его государство.
поэтому данные метода onsaveinstance-это точно вопрос...
7 ответов
Я думаю, что самый простой способ сделать это, например, в методе onViewCreated ():
if (savedInstanceState == null && !mAlreadyLoaded) {
mAlreadyLoaded = true;
// Do this code only first time, not after rotation or reuse fragment from backstack
}
потому что, когда android помещает фрагмент на backstack, он только уничтожает его представление, но не убивает сам экземпляр, поэтому mAlreadyLoaded будет по-прежнему истинным, когда фрагмент будет восстановлен из backstack.
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.
когда фрагмент идет в back-stack onDestroyView()
называется. Не onDestroy()
.
и когда фрагмент выскакивает из back-stack 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;
}
MAJOR EDIT: 15 октября 2013
Предыдущее объяснение (хранится ниже Для справки) терпит неудачу, когда приложение помещается в фоновом режиме и возвращается на передний план.
вместо этого лучше сравнить текущий размер backstack с тем, когда фрагмент был создан и помещен в backstack.
внимательно посмотрите на Рисунок 2. http://developer.android.com/guide/components/fragments.html#Creating
этот рисунок говорит вам, что когда фрагмент восстанавливается из 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();
}
}
Если вы добавили фрагмент в backstack, и после некоторых манипуляций вы скрываете его с помощью fragmentTransaction.скрыть(фрагмент), а затем восстановить его из backstack, как fragmentTransaction.шоу(fragmentManager.findFragmentByTag (фрагмент.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 метод, чтобы понять, это первый показ фрагмента или он восстановлен из backstack.