Как определить фрагмент, восстановленный из backstack - PullRequest
53 голосов
/ 27 октября 2011

Искал эту проблему некоторое время безрезультатно:

Как определить, что фрагмент восстанавливается из backstack? Я использую библиотеку совместимости и ListFragment внутри FragmentActivity. Когда элемент внутри ListFragment выбран, запускается новый фрагмент для замены ListFragment.

Я заметил, что, когда FragmentActivity останавливается, вызывается onSaveInstanceState фрагмента. Но когда фрагмент помещается в задний стек с помощью FragmentTransaction, onSaveInstanceState не вызывается, тогда методы жизненного цикла onCreateView и onActivityCreated вызываются с нулевым сохраненным набором переменных.

Я спрашиваю это, потому что я хочу загрузить некоторые данные, когда фрагмент создается или восстанавливается, но не так, когда пользователь возвращается через. backstack.

Я смотрел на Как проверить, был ли фрагмент восстановлен из backstack? но хочу добавить больше деталей в надежде, что это вызовет ответ.

Edit: только что заметил http://developer.android.com/reference/android/app/Fragment.html#onSaveInstanceState(android.os.Bundle) говорит

Обратите внимание: этот метод может быть вызван в любое время до onDestroy (). Во многих ситуациях фрагмент может быть в основном разрушен (например, когда он помещен в задний стек без отображения пользовательского интерфейса), но его состояние не будет сохранено до тех пор, пока его собственное действие фактически не должно будет сохранить свое состояние.

Так что оSaveInstanceState определенно не может быть и речи ...

Ответы [ 7 ]

38 голосов
/ 22 июля 2012

Я думаю, что самый простой способ сделать это, например, с помощью метода onViewCreated ():

if (savedInstanceState == null && !mAlreadyLoaded) {
    mAlreadyLoaded = true;

    // Do this code only first time, not after rotation or reuse fragment from backstack
}

Потому что, когда android помещает фрагмент в backstack, он только разрушает его представление, но не уничтожает сам экземпляр, так что mAlreadyLoaded будет все равно true, когда фрагмент будет восстановлен из backstack.

32 голосов
/ 27 октября 2011
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.

19 голосов
/ 07 января 2016

Когда фрагмент переходит в бэк-стек, вызывается 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;
}
8 голосов
/ 24 марта 2013

ОСНОВНОЕ РЕДАКТИРОВАНИЕ : 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();
    }
}
4 голосов
/ 25 сентября 2013

Если вы добавили фрагмент в backstack, и после некоторых манипуляций вы скрываете его, используя fragTransaction.hide (фрагмент), а затем восстанавливаете его из обратного стека, как fragTransaction.show (фрагментManager.findFragmentByTag (фрагмент.Вы можете переопределить onHiddenChanged (логическое скрытое)

@Override
public void onHiddenChanged(boolean hidden) {
    // TODO Auto-generated method stub
    super.onHiddenChanged(hidden);
    if (!hidden) {
        //fragment became visible
        //your code here
    }
}
0 голосов
/ 18 июля 2015
Fragment.getFragmentManager() == null 

до добавления и после появления

0 голосов
/ 16 августа 2012

В некоторых случаях вы можете использовать метод isVisible , чтобы понять, является ли он первым фрагментом или он восстановлен из backstack.

...