android - studio - En Fragmento en el botón Atrás, la actividad está en blanco
regresar a un activity anterior android (9)
Casi lo mismo que la respuesta de Xamarin.Android
, pero en Xamarin.Android
Manera de Xamarin.Android
:
Fragmento de carga ( escribí el método de ayuda para eso, pero no es necesario ):
public void LoadFragment(Activity activity, Fragment fragment, string fragmentTitle = "")
{
var fragmentManager = activity.FragmentManager;
var fragmentTransaction = fragmentManager.BeginTransaction();
fragmentTransaction.Replace(Resource.Id.mainContainer, fragment);
fragmentTransaction.AddToBackStack(fragmentTitle);
fragmentTransaction.Commit();
}
Botón Atrás ( en MainActivity
):
public override void OnBackPressed()
{
if (isNavDrawerOpen()) drawerLayout.CloseDrawers();
else
{
var backStackEntryCount = FragmentManager.BackStackEntryCount;
if (backStackEntryCount == 1) Finish();
else if (backStackEntryCount > 1) FragmentManager.PopBackStack();
else base.OnBackPressed();
}
}
Y el método isNavDrawerOpen
:
bool isNavDrawerOpen()
{
return drawerLayout != null && drawerLayout.IsDrawerOpen(Android.Support.V4.View.GravityCompat.Start);
}
Tengo una actividad y muchos fragmentos inflados en el mismo FrameLayout
<FrameLayout
android:id="@+id/content_frame"
android:layout_width="match_parent"
android:layout_height="match_parent" />
ejemplo: mainActivity> cualquier fragmento (presione el botón Atrás)> la actividad está en blanco.
En onCreate:
layout = (FrameLayout)findViewById(R.id.content_frame);
layout.setVisibility(View.GONE);
Cuando comienzo un fragmento:
FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
ft.replace(R.id.content_frame, profileFragment);
ft.addToBackStack(null);
ft.commit();
layout.setVisibility(View.VISIBLE);
Supongo que necesito hacer que la visibilidad de FrameLayout GONE
nuevamente en la parte posterior presionada, pero ¿cómo hago esto?
Intenté onBackPressed
y establecí layout.setVisibility(View.GONE);
pero no puedo regresar a través de fragmentos, ya que voy directamente a la página principal.
En un proyecto personal reciente, resolví esto al no llamar a addToBackStack
si la pila está vacía.
// don''t add the first fragment to the backstack
// otherwise, pressing back on that fragment will result in a blank screen
if (fragmentManager.getFragments() != null) {
transaction.addToBackStack(tag);
}
Aquí está mi implementación completa:
String tag = String.valueOf(mCurrentSectionId);
FragmentManager fragmentManager = mActivity.getSupportFragmentManager();
Fragment fragment = fragmentManager.findFragmentByTag(tag);
if (fragment != null) {
// if the fragment exists then no need to create it, just pop back to it so
// that repeatedly toggling between fragments doesn''t create a giant stack
fragmentManager.popBackStackImmediate(tag, 0);
} else {
// at this point, popping back to that fragment didn''t happen
// So create a new one and then show it
fragment = createFragmentForSection(mCurrentSectionId);
FragmentTransaction transaction = fragmentManager.beginTransaction()
.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN)
.replace(R.id.main_content, fragment, tag);
// don''t add the first fragment to the backstack
// otherwise, pressing back on that fragment will result in a blank screen
if (fragmentManager.getFragments() != null) {
transaction.addToBackStack(tag);
}
transaction.commit();
}
La solución de irscomp funciona si desea finalizar la actividad cuando se presiona el botón Atrás en el primer fragmento. Pero si desea rastrear todos los fragmentos y volver de uno a otro en orden inverso, agregue todos los fragmentos para apilar con:
ft.addToBackStack(null);
y luego, agregue esto al final de onCreate () para evitar que se presione la última pantalla en blanco; puede usar getSupportFragmentManager () o getFragmentManager () dependiendo de su API:
FragmentManager fm = getSupportFragmentManager();
fm.addOnBackStackChangedListener(new OnBackStackChangedListener() {
@Override
public void onBackStackChanged() {
if(getSupportFragmentManager().getBackStackEntryCount() == 0) finish();
}
});
Palabras finales: no sugiero que use esta solución, porque si pasa de fragment1 a fragment 2 y viceversa 10 veces, cuando presiona el botón Atrás 10 veces lo hará en orden inverso, lo que los usuarios no querrán.
Lo siento por la respuesta tardía.
No tiene que agregar ft.addToBackStack (null); mientras agrega el primer fragmento.
FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
ft.replace(R.id.content_frame, profileFragment);
// ft.addToBackStack(null); --remove this line.
ft.commit();
// ... rest of code
Puede anular en onBackPressed
y controlar para ver si hay algo en la copia posterior.
@Override
public void onBackPressed() {
int fragments = getFragmentManager().getBackStackEntryCount();
if (fragments == 1) {
// make layout invisible since last fragment will be removed
}
super.onBackPressed();
}
Si desea rastrear por los fragmentos, debe anular el método onBackPressed
, como este
public void onBackPressed() {
if (getFragmentManager().getBackStackEntryCount() == 1) {
finish();
} else {
super.onBackPressed();
}
}
Si tiene más de un fragmento utilizado en la actividad o incluso si tiene solo un fragmento, entonces el primer fragmento no debería tener addToBackStack definido. Como esto permite la navegación hacia atrás y antes de este fragmento, se mostrará el diseño de la actividad vacía.
// fragmentmaganer.addToBackStack() // dont include this for your first fragment.
Pero para el otro fragmento debe tener esto definido, de lo contrario, la parte posterior no se desplazará a la pantalla anterior (fragmento) en lugar de que la aplicación se cierre.
Todavía no pude solucionar el problema a través de getBackStackEntryCount()
y resolví mi problema al convertir también la página principal en un fragmento, por lo que al final tengo una actividad solo con FrameLayout
; y todos los demás fragmentos, incluida la página principal, se inflan en ese diseño. Esto resolvió mi problema.
@Override
public void onBackPressed() {
DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
if (drawer.isDrawerOpen(GravityCompat.START)) {
drawer.closeDrawer(GravityCompat.START);
}
else {
int fragments = getSupportFragmentManager().getBackStackEntryCount();
if (fragments == 1) {
finish();
} else {
if (getFragmentManager().getBackStackEntryCount() > 1) {
getFragmentManager().popBackStack();
} else {
super.onBackPressed();
}
}
}
}
Para agregar un fragmento
getSupportFragmentManager().beginTransaction()
.replace(R.id.layout_main, dashboardFragment, getString(R.string.title_dashboard))
.addToBackStack(getString(R.string.title_dashboard))
.commit();