Как определить фрагмент, восстановленный из 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.


Fragment.getFragmentManager() == null 

перед добавлением и после выскочил