tutorial studio navegar implement how fragments example entre ejemplo dinamicos diferencia activity android android-fragments fragmenttransaction

android - studio - FragmentTransaction: replace y addToBackStack no funcionan juntos?



how to implement fragments in android studio (2)

addToBackstack crea una instantánea de su estado de fragmentos. Lo que significa que cuando presionas el botón Atrás, en realidad estás volviendo al último estado en el que se addToBackstack .

En tu caso, agregas un Fragmento. El botón Atrás eliminaría este fragmento añadido. Cuando llamas a replace, y lo agregas nuevamente a backstack, ahora tienes dos estados en la backstack (1. cuando tenías el primer fragmento agregado, 2. cuando no tenías fragmentos agregados). Si usa el botón Atrás para eliminar el fragmento actual, no use addToBackstack. Solo use addToBackstack cuando desee conservar el estado de los fragmentos en una vista.

Soy bastante nuevo en el desarrollo de Android y ahora tengo un comportamiento extraño.

  • Tengo un FrameLayout vacío para ser el contenedor de un fragmento.
  • Si el usuario presiona un botón por primera vez, genera un nuevo Fragmento y ponlo dentro del contenedor.
  • Si el usuario presiona un botón más adelante y hay un fragmento existente dentro del contenedor, reemplace el existente por uno nuevo.
  • Si el usuario presiona el botón Atrás, extraiga el fragmento dentro del contenedor.

Aquí está mi código

public void showFragment(View v) { FragmentA f = new FragmentA(); FragmentManager fm = getSupportFragmentManager(); String tag = f.getFragmentTag(); // instance method of a to get a tag FragmentTransaction ft = fm.beginTransaction(); ft.setCustomAnimations(R.anim.slide_in_top, 0, 0, R.anim.slide_out_top); ft.replace(R.id.container, f, tag); ft.addToBackStack(tag); ft.commit(); } @Override public void onBackPressed() { FragmentManager fm = getSupportFragmentManager(); if (fm.getBackStackEntryCount() > 0) { fm.popBackStack(); } else { super.onBackPressed(); } }

Cuando el usuario presiona el botón por primera vez, se comporta como esperaba, agrega un nuevo fragmento al contenedor. Pero, la segunda vez que el usuario presiona el botón mientras el contenedor todavía contiene un fragmento, en lugar de reemplazarlo, agrega uno nuevo sobre el existente. Entonces, 2 fragmentos dentro del contenedor, 2 presione atrás para eliminar todo el fragmento.

Descubrí que si elimino la línea

ft.addToBackStack();

Y vuelva a trabajar el método onBackPress () como sigue, funciona de nuevo como esperaba (1 fragmento en contenedor a la vez)

básicamente, eliminar fragmento manualmente en lugar del método popFromBackStack

private FragmentA currentFragment = null; // to hold the reference to exising fragment, if any. @Override public void onBackPressed() { if (currentFragment != null) { FragmentManager fm = getSupportFragmentManager(); FragmentTransaction ft = fm.beginTransaction(); ft.setCustomAnimations(0, R.anim.slide_out_top); ft.remove(currentFragment); ft.commit(); currentFragment = null; } else { super.onBackPressed(); } }

Entonces, mi pregunta es

  • reemplazar y addToBackStack no funciona en conjunto?
  • o, ¿hice algo mal?

Aprecie todos los comentarios y sugerencias.


Para aquellos que todavía están buscando una solución.

En la clase de Activity principal (que hospeda los fragmentos) solo anula onBackPressed() .

@Override public void onBackPressed() { if (getFragmentManager().getBackStackEntryCount() > 0 ){ getFragmentManager().popBackStack(); } else { super.onBackPressed(); } }

No hay método onBackPressed() en fragmento, y este método es solo para la activity . Entonces, cuando presionamos la tecla Atrás, se muestra el comportamiento predeterminado de la activity , que es

irás a la actividad anterior (si hay alguna) o la aplicación saldrá.

Ahora necesitamos anular este método para decirle a la activity que cuando presionamos la tecla de retroceso, si hay algún fragmento en la pila de respaldo, los addToBackStack() y es cuando addToBackStack() en la imagen). De lo contrario, siga el comportamiento predeterminado.

encuentra más detalles aquí