android - terminales - ¿Es esta la manera correcta de limpiar el Fragmento de la pila trasera al dejar una pila profundamente anidada?
limpiar los bornes de la bateria con limon (6)
Estoy usando la biblioteca de compatibilidad de Android para implementar fragmentos y he extendido la muestra de diseño para que un fragmento contenga un botón que dispare otro fragmento.
En el panel de selección de la izquierda, tengo 5 elementos seleccionables: ABCDE
.
Cada uno carga un fragmento (a través de FragmentTransaction:replace
) en el panel de detalles - abcde
Ahora he extendido el fragmento e
para que contenga un botón que carga otro fragmento e1
también en el panel de detalles. He hecho esto en el método onClick de fragment e
de la siguiente manera:
FragmentTransaction ft = getActivity().getSupportFragmentManager().beginTransaction();
ft.replace(R.id.details_frag, newFrag);
ft.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN);
ft.addToBackStack(null);
ft.commit();
Si hago las siguientes selecciones:
E - e - e1 - D - E
Entonces el fragmento e
está en el panel de detalles. Esto está bien y lo que quiero. Sin embargo, si presiono el botón back
en este punto, no hace nada. Tengo que hacer clic dos veces porque e1
todavía está en la pila. Además, después de hacer clic, obtuve una excepción de puntero nulo en onCreateView:
Para ''resolver'' este problema, agregué lo siguiente siempre que se selecciona ABCDE
:
FragmentManager fm = getActivity().getSupportFragmentManager();
for(int i = 0; i < fm.getBackStackEntryCount(); ++i) {
fm.popBackStack();
}
Me pregunto si esta es la solución correcta o si debería estar haciendo algo diferente.
Bueno, hay algunas maneras de hacerlo, dependiendo del comportamiento previsto, pero este enlace debe ofrecerle todas las mejores soluciones y no es sorprendente que sea de Dianne Hackborn.
http://groups.google.com/group/android-developers/browse_thread/thread/d2a5c203dad6ec42
Esencialmente tienes las siguientes opciones
- Use un nombre para su estado inicial de pila posterior y use
FragmentManager.popBackStack(String name, FragmentManager.POP_BACK_STACK_INCLUSIVE)
. - Utilice
FragmentManager.getBackStackEntryCount()
/getBackStackEntryAt().getId()
para recuperar el ID de la primera entrada en la pila posterior, yFragmentManager.popBackStack(int id, FragmentManager.POP_BACK_STACK_INCLUSIVE)
. -
FragmentManager.popBackStack(null, FragmentManager.POP_BACK_STACK_INCLUSIVE)
supone queFragmentManager.popBackStack(null, FragmentManager.POP_BACK_STACK_INCLUSIVE)
extrae toda la pila posterior ... Creo que la documentación es incorrecta. (En realidad, supongo que simplemente no cubre el caso en el que pasa enPOP_BACK_STACK_INCLUSIVE
),
Estoy usando un código similar al que usa el ciclo while, pero llamo el conteo de entrada en cada ciclo ... así que supongo que es algo más lento
FragmentManager manager = getFragmentManager();
while (manager.getBackStackEntryCount() > 0){
manager.popBackStackImmediate();
}
Gracias a la respuesta de Joachim , uso el código para borrar finalmente la entrada de la pila trasera.
// In your FragmentActivity use getSupprotFragmentManager() to get the FragmentManager.
// Clear all back stack.
int backStackCount = getSupportFragmentManager().getBackStackEntryCount();
for (int i = 0; i < backStackCount; i++) {
// Get the back stack fragment id.
int backStackId = getSupportFragmentManager().getBackStackEntryAt(i).getId();
fm.popBackStack(backStackId, FragmentManager.POP_BACK_STACK_INCLUSIVE);
} /* end of for */
He investigado mucho para limpiar Backstack, y finalmente veo Transaction BackStack y su administración . Aquí está la solución que mejor funcionó para mí.
// CLEAR BACK STACK.
private void clearBackStack() {
final FragmentManager fragmentManager = getSupportFragmentManager();
while (fragmentManager.getBackStackEntryCount() != 0) {
fragmentManager.popBackStackImmediate();
}
}
El método anterior recorre todas las transacciones en la pila de respaldo y las elimina inmediatamente de a una por vez.
Nota: el código anterior algunas veces no funciona y me enfrento a ANR debido a este código, así que por favor no intente esto.
El método de actualización a continuación elimina todos los registros de ese "nombre" de backstack.
FragmentManager fragmentManager = getSupportFragmentManager();
fragmentManager.popBackStack("name",FragmentManager.POP_BACK_STACK_INCLUSIVE);
- nombre Si no es nulo, este es el nombre de un estado anterior a buscar; si se encuentra, todos los estados hasta ese estado serán reventados. los
- El indicador POP_BACK_STACK_INCLUSIVE se puede usar para controlar si el estado nombrado se ha reventado. Si es nulo, solo aparece el estado superior.
La otra solución limpia si no desea mostrar todas las entradas de la pila ...
getSupportFragmentManager().popBackStack(null, FragmentManager.POP_BACK_STACK_INCLUSIVE);
getSupportFragmentManager().beginTransaction().replace(R.id.home_activity_container, fragmentInstance).addToBackStack(null).commit();
Esto limpiará la pila primero y luego cargará un nuevo fragmento, por lo que en cualquier punto dado tendrás solo un único fragmento en la pila
// pop back stack all the way
final FragmentManager fm = getSherlockActivity().getSupportFragmentManager();
int entryCount = fm.getBackStackEntryCount();
while (entryCount-- > 0) {
fm.popBackStack();
}