2012-02-09 27 views
33

enter image description hereAndroid Eliminar Fragmento y ver desde BackStack

realizo esta pregunta se ha hecho antes, sin embargo las respuestas anteriores me han conseguido hasta el momento. El escenario es el siguiente: tenemos un fragmento de panel (A), que lleva al usuario a una pantalla de inicio de sesión (B). En el inicio de sesión exitoso van a una vista de lista (c). En reversa, me gustaría volver a A, ya que el usuario no tendrá que volver a ver la pantalla de inicio de sesión. Además de un inicio de sesión exitoso, almacenamos los detalles en las preferencias compartidas y automatizamos el inicio de sesión en B la próxima vez, que funciona según lo planeado.

I tienen el siguiente método FragmentHelper:

public static void goToNextFragement(Fragment fragment, int container, boolean addToBackStack, Fragment ctx) 
    { 
     // Create new fragment and transaction 
     FragmentTransaction transaction = ctx.getSupportFragmentManager().beginTransaction(); 
     transaction.setCustomAnimations(R.anim.slide_in_left, R.anim.slide_out_right); 
     // Replace whatever is in the fragment_container view with this fragment, 
     // and add the transaction to the back stack 
     transaction.replace(container, fragment); 

     if(addToBackStack) 
      transaction.addToBackStack(null); 

     // Commit the transaction 
     transaction.commit(); 
    } 

en la transacción de B a C fijo el addToBackStack Boolean como falso de modo que el transaction.addToBackStack(null); no se llama. De nuevo, esto funciona bien, pero después es donde comienza mi problema.

Cuando el usuario presiona de nuevo en C y vuelve a A todavía puede ver la vista inflada de C en la vista de A.

sería apreciada Cualquier ayuda. Espero que mi diagrama ayude a mantener esto simple.

Respuesta

1

par de maneras de manejar esta situación:

  1. que tenía un flujo similar en mi aplicación y la forma en que lo resolvió fue reemplazando el fragmento de inicio de sesión con un AlertDialog que ha despedido de la actividad principal. Entonces en su caso, el fragmento A aparece en la pantalla y si la actividad principal cree que necesita mostrar el diálogo de inicio de sesión, muestra el AlertDialog. Esto funcionó para mí.

  2. Cuando el fragmento A está habilitado, puede verificar si el fragmento C está presente preguntando a FragmentManager. Si existe, elimínelo.

+0

AlertDialogue era el camino a seguir. Gracias por compartir su experiencia. –

+16

Esto es más bien una solución provisional, no una solución real, ¿o sí? – Brian

+2

esto no es aceptable responde –

0

No decirle a la FM que desea que la transición de B a C se agregue a BackStack significa que cuando devuelve el golpe, la FM no tiene registro de agregar C, por lo que no lo elimina.

+0

Bien, pensé que tal vez el caso, sin embargo (a riesgo de sonar desagradecido por la ayuda, que no soy) esto proporciona un análisis del problema y no la solución. ¿Tiene alguna idea de solucionar este problema? –

+0

En la parte superior de mi cabeza, puedes eliminar manualmente ese fragmento, pero probablemente esa no sea la mejor opción. Más allá de esto, tendrás que hacer tu propia tarea. –

21

que resolvieron este .. dentro de una línea ...

getFragmentManager().popBackStack(); 

o

getSupportFragmentManager().popBackStack() 

esto funciona cuando se está añadiendo fragmentos y mantener backstack (no sustituir).

+0

respuesta real, gracias –

+1

Cuando saltas backstack antes de pasar del sistema 2 a 3 tratando de mostrar el fragmento 1. Cada vez que sacas el número de fragmento N intenta mostrar el número de fragmento (N-1). Y si te obligas a ir al fragmento 3 obtendrás NPE durante onCreateView de 1 fragmento ... – Yazon2006

6

F1 -> f2

Fragment2 f2 = new Fragment2(); 
this.getActivity().getSupportFragmentManager().beginTransaction().replace(R.id.main_content,f2).addToBackStack(null).commit(); 

nada fuera de lo común aquí. Que en el fragmento f2 este código te lleva al fragmento f3.

F2 -> f3

Fragment3 f3 = new Fragment3(); 
getActivity().getSupportFragmentManager().popBackStack(); 
getActivity().getSupportFragmentManager().beginTransaction().replace(R.id.main_content, f3).addToBackStack(null).commit(); 

No estoy seguro mediante la lectura de documentos si esto debería funcionar, se dice que este método de transacción Poping sea asíncrona, y tal vez una manera mejor sería llamar popBackStackImmediate() . Pero hasta donde puedo decir en mis dispositivos, funciona perfectamente.

la citada alternativa sería:

final FragmentActivity activity = getActivity(); 
activity.getSupportFragmentManager().popBackStackImmediate(); 
activity.getSupportFragmentManager().beginTransaction().replace(R.id.main_content, f3).addToBackStack(null).commit(); 

Aquí hay realmente será breve volver a la F1 beofre de pasar a f3, por lo que un pequeño problema allí.

Esto es en realidad todo lo que tiene que hacer y esto answer también le puede ayudar a la porción ..

+0

tu solución es muy perfecta para mi problema, me salvas el tiempo Nepster. –

0

Paso 1: Cuando estás en el Fragmento A y desea abrir fragmento B

getFragmentManager().beginTransaction() 
.replace(android.R.id.content, new FragmentB(), FragmentB.class.getName() 
.addToBackStack(null) 
.commit(); 

Paso 2: Cuando estás en el fragmento B, y desea abrir Fragmento C

getFragmentManager().beginTransaction() 
.replace(android.R.id.content, new FragmentC(), FragmentC.class.getName() 
.disallowAddToBackStack() // << this to make Fragment B, not included in the backstack 
.commit(); 

Paso 3: Cuando you'in en el Fragmento C, y el dispositivo pulsando el botón atrás o que getFragmentManager().popBackStack(); se abrirá el Fragmento A.

PD: En la actividad usa este getSupportFragmentManager(). Si está en Fragment use este getFragmentManager()

0

Hola, solo quería compartir la solución elegante que encontré.

public static void performNoBackStackTransaction(FragmentManager fragmentManager, String tag, Fragment fragment) { 
final int newBackStackLength = fragmentManager.getBackStackEntryCount() +1; 

fragmentManager.beginTransaction() 
    .replace(R.id.content, fragment, tag) 
    .addToBackStack(tag) 
    .commit(); 

fragmentManager.addOnBackStackChangedListener(new FragmentManager.OnBackStackChangedListener() { 
    @Override 
    public void onBackStackChanged() { 
    int nowCount = fragmentManager.getBackStackEntryCount(); 
    if (newBackStackLength != nowCount) { 
     // we don't really care if going back or forward. we already performed the logic here. 
     fragmentManager.removeOnBackStackChangedListener(this); 

     if (newBackStackLength > nowCount) { // user pressed back 
     fragmentManager.popBackStackImmediate(); 
     } 
    } 
    } 
}); 
} 

Source with explained logic.

Cuestiones relacionadas