Join FlipAndroid.COM Telegram Group: https://t.me/joinchat/F_aqThGkhwcLzmI49vKAiw


Comprensión fragmentos backstack

Por lo tanto, hay algunas preguntas similares, pero no he encontrado una sola solución de este problema. La documentación oficial de Android parece intuitiva, pero cuando implemento una aplicación con un flujo de trabajo más complicado, la fragilidad de los fragmentos se vuelve desordenada y cosas extrañas comienzan a suceder. Desarrollé un esqueleto para aplicaciones simples, con la idea de una sola actividad a la que se puede acceder por sus fragmentos para iniciar otros fragmentos. Así es como lo hice:

1- Permito que mi actividad principal implemente una interfaz llamada "FragmentDelegate"

public interface FragmentDelegate { public void startFragment(CCFragment fragment, boolean addToBackStack); } 

2- La implementación del método startFrargment:

 @Override public void startFragment(CCFragment fragment, boolean addToBackStack) { FragmentManager fragmentManager = getSupportFragmentManager(); fragment.setFragmentDelegate(this); FragmentTransaction fragmentTransaction = fragmentManager .beginTransaction(); fragmentTransaction.setCustomAnimations(R.anim.slide_in_right, R.anim.slide_out_left, R.anim.slide_in_left, R.anim.slide_out_right); fragmentTransaction.replace(CONTENT_VIEW_ID, fragment, "callerFragmentClassName"); if (addToBackStack) fragmentTransaction.addToBackStack("callerFragmentClassName"); fragmentTransaction.commitAllowingStateLoss(); } 

Lo bueno de esto es, puedo llamar desde cualquier fragmento:

 mFragmentDelegate.startFragment(aNewFragment, addToBackStack); 

Aceptar ahora pensar en el siguiente caso:

Comienzo mi actividad con un fragmento inicial, digamos fragmento A. Del fragmento A, llamo a la Actividad de la Cámara para obtener un resultado. Cuando llega el resultado, comienzo Fragmento B (añadiendo A al backstack). Desde BI inicie Fragmento C sin agregar B a la pila posterior. Así que tenemos esto en el backstack:

[A] [C]

Si presiono el botón de retroceso, vuelvo a A. Si repito el proceso, el backstack se ensucia y cuando presiono de nuevo, me lleva al fragmento C una y otra vez …

Sé que esto es difícil de entender (y más difícil de explicar, porque el inglés no es mi lengua materna), pero si alguien me explicara cómo funcionan los fragmentos de androide backstack o proporcionan algún tipo de esqueleto para una aplicación, sería genial.

  • ¿Cómo puedo crear la superposición de tutoriales gris semi-transparente en Android?
  • OnCreateOptionsMenu en un ciclo de vida de Fragmento
  • CustomAnimation al llamar a popBackStack en un FragmentManager
  • ¿Es Fragmento una actividad? (Androide)
  • La actividad de NavigationDrawer está llena de fragmentos de retorno de llamada y lógica de aplicaciones
  • Android Reorder Fragment Backstack
  • Añadir acción de botón en la notificación personalizada
  • Recuperar Contexto de un fragmento
  • 4 Solutions collect form web for “Comprensión fragmentos backstack”

    Explicación:

    Cuando el FragmentManager revierte las FragmentTransactions guardadas (por ejemplo, el usuario hace clic en el botón Back o llama a algún método pop en él), ejecuta lo opuesto a la acción que se almacena en la FragmentTransaction guardada. Puedes ver el código exacto aquí , es bastante sencillo.

    En su caso, el tipo de operación guardada es 'reemplazar', por lo que revertir significa quitar todas las instancias de Fragmento agregadas y volver a agregar la eliminada. Así que cuando tienes una pila de fragmentos así:

    [A] [B]

    FragmentManager sabe, que es tiene que quitar la instancia [B] Fragmento y agregar el [A] en una operación pop. El problema es que reemplazaste [B] por [C]:

    [A] [C]

    Desafortunadamente, la entrada guardada del BackStack del fragmento no sabe acerca de [C]. Así que durante una operación pop, el FragmentManager volverá a agregar [A], no encontrará [B] por lo que no hace nada al respecto, y dejar [C] donde está.

    Solución

    Una posible solución para este problema es el uso de fragmentos de niños. Fragmento-A es un fragmento de nivel superior, pero Fragmento-B y Fragmento-C son fragmentos de un fragmento de Wrapper.

    Básicamente, cuando se navega al Fragmento-B, se reemplaza el fragmento-A con el fragmento Wrapper en una transacción guardada:

    [A] [B]

    Después, cuando el usuario navega a Fragmento-C, sólo se reemplazan los [B] de WrapperFragment con [C]:

    [A] [[C]]

    Cuando el usuario presiona el botón Atrás, regresaremos correctamente a Fragmento-A:

    [UN]

    Manifestación

    He ensamblado un proyecto GitHub para demostrar esta técnica.

    No puedo imaginar cómo terminaste con hacer estallar fragmentos de C una y otra vez sin una imagen completa de lo que hiciste, pero aquí lo que te equivocaste en backstack:

    • BackStack entrada BackStack realmente guarda el estado actual de FragmentManager entero, no solo un solo fragmento. Es decir, si realiza múltiples operaciones con múltiples fragmentos en una sola transacción y llama a addToBackStack() , guardará el estado de todos los fragmentos en la próxima transacción.

    • Cuando llamas a addToBackStack() el siguiente estado al backstack, es decir, en realidad, si has llamado addToBackStack() cuando has agregado un fragmento, realmente tienes un estado con B y un estado con A detrás de él – – [A] [B], no [A] [C].

    Te recomiendo que utilices este código y probar todo con depurador mirando un estado del objeto FragmentManager :

      int count = fragmentManager.getBackStackEntryCount(); fragmentTransaction.addToBackStack(String.valueOf(count)); 

    De esta forma, podrás localizar lo que realmente está pasando en tu aplicación.

    En primer lugar, recuerde:

      .replace() = .remove().add() 

    Algunas posibles soluciones

      public void onBackPressed(){ // here you have to remove your last fragment. super.onBackPressed(); } 

    ////////////////////////////////////////////////// /////////////////////////////////////////////

     @Override public boolean onKeyDown(int keyCode, KeyEvent event) { if (keyCode == KeyEvent.KEYCODE_BACK) { if (getSupportFragmentManager().getBackStackEntryCount() == 0) { this.finish(); return false; } else { getSupportFragmentManager().popBackStack(); removeCurrentFragment(); return false; } } return super.onKeyDown(keyCode, event); } public void removeCurrentFragment() { FragmentTransaction transaction = getSupportFragmentManager().beginTransaction(); Fragment currentFrag = getSupportFragmentManager().findFragmentById(R.id.detailFragment); if (currentFrag != null) transaction.remove(currentFrag); transaction.commit(); } 

    ////////////////////////////////////////////////// //////////////////////////////////////

    Para obtener más información sobre backstack de fragmentos Comprobar aquí y aquí

    Esto puede no parecer una solución, pero creo que es mejor si no usas fragmentos en situaciones como esta. Al principio tener sólo una Actividad y la sustitución de fragmentos a la demanda parece una gran idea, pero cuando se intenta construir su aplicación de esta manera las cosas se ensucian. (He estado allí y estoy hablando de experiencia). Administrar BackStack usted mismo es sólo uno de los problemas. A medida que vaya más lejos que terminar con una actividad con tantos en el código relacionado dentro de lo que no es genial en absoluto!

    Le sugiero que cree una actividad para cada fragmento que tiene y simplemente coloque su fragmento dentro de él. Sus actividades todavía pueden tener múltiples fragmentos en algunos casos (digamos tabletas o modo de paisaje) y uno en algún otro caso (como el modo retrato) Pero usted no tiene que usar el método de reemplazo más.

    Las actividades pueden tener la actividad de los padres para que el problema de BackStack se resuelva de la mejor manera posible como muchos otros problemas. Esto es sólo una sugerencia basada en la experiencia que tuve con fragmentos. Haz lo que mejor te parezca.

    FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.