Cómo determinar el fragmento restaurado de backstack


Ha estado buscando este problema durante un tiempo sin éxito ahora:

¿Cómo determinar que el fragmento se está restaurando desde backstack? Estoy usando la biblioteca de compatibilidad y un ListFragment dentro de un FragmentActivity. Cuando se selecciona un elemento dentro de ListFragment, se inicia un nuevo Fragmento para reemplazar el ListFragment.

He notado que cuando la FragmentActivity se detiene, se llama al Fragmentaveinstancestate del Fragmento. Pero cuando el fragmento se pone en la pila posterior vía FragmentTransaction, onaveinstancestate no se llama, luego los métodos de ciclo de vida onCreateView y onActivityCreated se llaman con null savedInstanceState Bundle.

Pregunto esto porque quiero cargar algunos datos cuando se crea o restaura el Fragmento, pero no es así cuando el usuario regresa a través. backstack.

He mirado ¿Cómo comprobar si el fragmento fue restaurado desde un backstack? pero quiero añadir más detalles con la esperanza de que esto incite a una respuesta.

Editar: me acabo de dar cuenta http://developer.android.com/reference/android/app/Fragment.html#onSaveInstanceState(android.os.Bundle) dice

Nota sin embargo: este método puede ser llamado en cualquier momento antes de onDestroy(). Hay muchas situaciones en las que un fragmento puede ser derribado en su mayoría (como cuando se coloca en la pila trasera sin mostrar la interfaz de usuario), pero su estado no se guardará hasta que su actividad propietaria realmente necesite guardar su estado.

So onSaveInstanceState está definitivamente fuera de la cuestión...

Author: Community, 2011-10-27

7 answers

Creo que la forma más simple es hacer esto por ejemplo en el método onViewCreated ():

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

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

Porque cuando Android poner fragmento en backstack, solo destruir su vista, pero no matar instancia en sí, por lo mAlreadyLoaded será todavía cierto cuando el fragmento se restaurará de backstack.

 36
Author: ATom,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-07-22 19:26:25
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.
                }
            }
        });

Utilice este addOnBackStackChangedListener.

 31
Author: Yashwanth Kumar,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-10-27 17:18:13

Cuando un fragmento va a back-stack onDestroyView() llamado. No onDestroy().

Y cuando un fragmento aparece de back-stack onCreateView() llamado. No onCreate().

Así que añade un boolean mIsRestoredFromBackstack para fragmentar y sigue como sigue:

@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;
}
 15
Author: David,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-01-07 11:07:56

GRAN EDICIÓN : Oct 15 2013

La explicación anterior (que se mantiene a continuación como referencia) falla cuando la aplicación se pone en segundo plano y se devuelve al primer plano.

En su lugar, es mejor comparar el tamaño actual del backstack con el que se creó el fragmento y se puso en el backstack.


Eche un buen vistazo a la Figura 2 en http://developer.android.com/guide/components/fragments.html#Creating

¿Qué esta figura te dice que cuando un fragmento se restaura desde el backstack, su onCreate() no se llama, mientras que su onCreateView () sí.


Por lo tanto, es posible que desee hacer algo como esto:

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
Author: Giorgos Kylafas,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-05-08 07:53:04

Si agregaste fragment a backstack, y después de alguna manipulación lo escondes usando FragmentTransaction.ocultar (fragmento) y luego restaurarlo de backstack como FragmentTransaction.mostrar(fragmentManager.findFragmentByTag (fragment.getName ())); puede sobrescribir onHiddenChanged (booleano oculto)

@Override
public void onHiddenChanged(boolean hidden) {
    // TODO Auto-generated method stub
    super.onHiddenChanged(hidden);
    if (!hidden) {
        //fragment became visible
        //your code here
    }
}
 4
Author: Inc,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-07-31 12:53:50

En algunos casos puedes usar el método IsVisible para entender si es la primera vez que se muestra un fragmento o si se restaura desde el backstack.

 0
Author: AlexKorovyansky,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-08-16 10:35:14
Fragment.getFragmentManager() == null 

Antes de añadido y después de popped

 0
Author: Wonson,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-07-18 10:22:09