web-dev-qa-db-fra.com

Comment déterminer le fragment restauré à partir de backstack

Vous recherchez ce problème depuis un certain temps sans résultat maintenant:

Comment déterminer si un fragment est en cours de restauration à partir de backstack? J'utilise la bibliothèque de compatibilité et un ListFragment dans une FragmentActivity. Lorsqu'un élément dans ListFragment est sélectionné, un nouveau fragment est démarré pour remplacer le ListFragment.

J'ai remarqué que lorsque FragmentActivity est mis en pause, onSaveInstanceState du Fragment est appelé. Mais lorsque le fragment est placé dans la pile arrière via FragmentTransaction, onSaveInstanceState n'est pas appelé, puis les méthodes de cycle de vie onCreateView et onActivityCreated sont appelées avec le bundle saveInstanceState null.

Je pose cette question parce que je veux charger certaines données lorsque le fragment est créé ou restauré, mais pas lorsque l'utilisateur revient via. backstack.

J'ai regardé Comment vérifier si le fragment a été restauré à partir d'un backstack? mais je veux ajouter plus de détails dans l'espoir que cela incite à une réponse.

Edit: vient de remarquer http://developer.Android.com/reference/Android/app/Fragment.html#onSaveInstanceState (Android.os.Bundle) dit

Remarque cependant: cette méthode peut être appelée à tout moment avant onDestroy (). Il existe de nombreuses situations où un fragment peut être principalement détruit (comme lorsqu'il est placé sur la pile arrière sans affichage de l'interface utilisateur), mais son état ne sera pas enregistré jusqu'à ce que son activité de propriétaire ait réellement besoin de sauvegarder son état.

Donc onSaveInstanceState est définitivement hors de question ...

53
dvd

Je pense que le moyen le plus simple est de le faire par exemple dans la méthode onViewCreated ():

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

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

Parce que lorsque Android met un fragment sur backstack, il ne détruit que sa vue, mais ne tue pas l'instance elle-même, donc mAlreadyLoaded sera toujours vrai lorsque le fragment sera restauré à partir du backstack.

38
ATom
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.
                }
            }
        });

utilisez cet addOnBackStackChangedListener.

32
Yashwanth Kumar

Lorsqu'un fragment va dans la pile arrière, onDestroyView() est appelée. Pas onDestroy().

Et lorsqu'un fragment surgit de la pile arrière onCreateView() appelée. Pas onCreate().

Alors ajoutez un boolean mIsRestoredFromBackstack pour fragmenter et suivre comme suit:

@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;
}
20
David

MODIFICATION MAJEURE : 15 octobre 2013

L'explication précédente (conservée ci-dessous pour référence) échoue lorsque l'application est mise en arrière-plan et ramenée au premier plan.

Au lieu de cela, il est préférable de comparer la taille actuelle du backstack avec celle lorsque le fragment a été créé et placé dans le backstack.


Jetez un coup d'œil à la figure 2 dans http://developer.Android.com/guide/components/fragments.html#Creating

Ce que cette figure vous dit, c'est que lorsqu'un fragment est restauré à partir du backstack, son onCreate () n'est pas appelé, tandis que son onCreateView () l'est.


Donc, vous voudrez peut-être faire quelque chose comme ceci:

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();
    }
}
8
Giorgos Kylafas

Si vous avez ajouté un fragment à backstack, et après une certaine manipulation, vous le cachez à l'aide de fragmentTransaction.hide (fragment), puis le restaurez à partir de backstack comme fragmentTransaction.show (fragmentManager.findFragmentByTag (fragment.getName ())); vous pouvez remplacer onHiddenChanged (booléen masqué)

@Override
public void onHiddenChanged(boolean hidden) {
    // TODO Auto-generated method stub
    super.onHiddenChanged(hidden);
    if (!hidden) {
        //fragment became visible
        //your code here
    }
}
4
Inc

Dans certains cas, vous pouvez utiliser la méthode isVisible pour comprendre si elle montre d'abord un fragment ou si elle est restaurée à partir du backstack.

0
AlexKorovyansky