Подтвердить что ты не робот

Как определить фрагмент, восстановленный из backstack

Некоторое время поиск этой проблемы не имел успеха:

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

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

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

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

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

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

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

4b9b3361

Ответ 1

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

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

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

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

Ответ 2

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.

Ответ 3

Когда фрагмент переходит в обратный стек 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;
}

Ответ 4

ОСНОВНОЕ РЕДАКТИРОВАНИЕ: октябрь 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();
    }
}

Ответ 5

Если вы добавили фрагмент в backstack, и после некоторых манипуляций вы спрячете его с помощью фрагмента фрагмента (фрагмент), а затем восстановите его из backstack, например, фрагментTransaction.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
    }
}

Ответ 6

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

Ответ 7

Fragment.getFragmentManager() == null 

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