from - Android: volver al fragmento anterior en la prensa trasera
communicating fragment (5)
He implementado Navigation Drawer, que es una subclase de Activity. Tengo muchos fragmentos en mi solicitud. Mi pregunta va aqui
Imagina que hay 3 fragmentos:
Fragment_1: Fragmento_2: Fragmento_3
Cuando inicio mi aplicación, Fragment_1 se carga Cuando hago clic en algunos componentes en Fragment_1, me navego a Fragment_2 y así sucesivamente ..
Entonces es como
Fragment_1> Fragmento_2> Fragmento_3
Cuando presiono la tecla Atrás desde Fragment_2, me navego de nuevo a Fragment_1 Pero cuando presiono la tecla Atrás desde Fragment_3, me navego de nuevo a Fragment_1 (en lugar de Fragment_2)
Quiero algo como esto en mi aplicación al presionar la tecla Atrás
Fragment_1 <Fragmento_2 <Fragmento_3
He utilizado Fragment, FragmentManager, FragmentTransaction de la siguiente manera:
MyFragment fragment = new MyFragment();
FragmentManager fragmentManager = getFragmentManager();
fragmentManager.beginTransaction().replace(R.id.content_frame, fragment).addToBackStack(null)commit();
e intenté sobrescribir onBackPressed () en mi MainActivity:
@Override
public void onBackPressed() {
getFragmentManager().popBackStack(null, FragmentManager.POP_BACK_STACK_INCLUSIVE);
int count = getFragmentManager().getBackStackEntryCount();
if (count == 0)
super.onBackPressed();
}
Actualice su método Activity#onBackPressed()
para:
@Override
public void onBackPressed() {
if (getFragmentManager().getBackStackEntryCount() > 0) {
getFragmentManager().popBackStack();
} else {
super.onBackPressed();
}
}
La razón por la que su implementación no funciona es porque el método FragmentManager#popBackStack()
es asíncrono y no sucede justo después de que se llama.
De la documentación:
Esta función es asíncrona: encola la solicitud para que aparezca, pero la acción no se realizará hasta que la aplicación vuelva a su bucle de eventos.
Aquí está el código de trabajo y probado por mí, Esto te ayudará
private static final int TIME_INTERVAL = 2000;
private long mBackPressed;
private void applyExit() {
if (mBackPressed + TIME_INTERVAL > System.currentTimeMillis()) {
finish();
} else {
Toast.makeText(this,"Press Again to exit",Toast.LENGTH_LONG).show();
}
mBackPressed = System.currentTimeMillis();
}
@Override
public void onBackPressed() {
fm = getSupportFragmentManager();
if (drawer.isDrawerOpen(GravityCompat.START)) {
drawer.closeDrawer(GravityCompat.START);
}
if (fm.getFragments().size() <= 1) {
applyExit();
} else {
for (Fragment frag : fm.getFragments()) {
if (frag == null) {
applyExit();
return;
}
if (frag.isVisible()) {
FragmentManager childFm = frag.getChildFragmentManager();
if (childFm.getFragments() == null) {
super.onBackPressed();
return;
}
if (childFm.getBackStackEntryCount() > 0) {
childFm.popBackStack(null, FragmentManager.POP_BACK_STACK_INCLUSIVE);
return;
} else {
fm.popBackStack(null, FragmentManager.POP_BACK_STACK_INCLUSIVE);
return;
}
}
}
}
}
El tric está en FragmentManager#executePendingTransactions();
.
Esto es lo que uso para los fragmentos anidados también ...
/**
* if there is a fragment and the back stack of this fragment is not empty,
* then emulate ''onBackPressed'' behaviour, because in default, it is not working.
*
* @param fm the fragment manager to which we will try to dispatch the back pressed event.
* @return {@code true} if the onBackPressed event was consumed by a child fragment, otherwise
*/
public static boolean dispatchOnBackPressedToFragments(FragmentManager fm) {
List<Fragment> fragments = fm.getFragments();
boolean result;
if (fragments != null && !fragments.isEmpty()) {
for (Fragment frag : fragments) {
if (frag != null && frag.isAdded() && frag.getChildFragmentManager() != null) {
// go to the next level of child fragments.
result = dispatchOnBackPressedToFragments(frag.getChildFragmentManager());
if (result) return true;
}
}
}
// if the back stack is not empty then we pop the last transaction.
if (fm.getBackStackEntryCount() > 0) {
fm.popBackStack();
fm.executePendingTransactions();
return true;
}
return false;
}
y en mi onBackPressed
:
if (!FragmentUtils.dispatchOnBackPressedToFragments(fm)) {
// if no child fragment consumed the onBackPressed event,
// we execute the default behaviour.
super.onBackPressed();
}
Tienes que implementar tu propia implementación de backstack como se explica aquí
Separar la pila posterior para cada pestaña en Android usando fragmentos
Puede llamar a popFragments () siempre que haga clic en el botón Atrás en un fragmento y llame a pushFragments () cuando navegue de un Fragmento a otro.
en breve,
public void onBackPressed()
{
FragmentManager fm = getActivity().getSupportFragmentManager();
fm.popBackStack();
}
Use este código en el cambio de pestaña en su actividad principal para borrar la pila.
int count = getFragmentManager().getBackStackEntryCount();
if(count>0){
for (int i = 0; i <count; i++) {
getFragmentManager().popBackStack();
}
}
Luego presiona Atrás de tu actividad principal haz esto
int count = getFragmentManager().getBackStackEntryCount();
if (count == 0) {
super.onbackpressed();
}
else {
getFragmentManager().popBackStack();
}
}