Estoy aprendiendo a usar fragmentos. Tengo tres instancias de Fragment
eso que se inicializan en la parte superior de la clase. Estoy agregando el fragmento a una actividad como esta:
Declarando e inicializando:
Fragment A = new AFragment();
Fragment B = new BFragment();
Fragment C = new CFragment();
Reemplazar / Agregar:
FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
ft.replace(R.id.content_frame, A);
ft.addToBackStack(null);
ft.commit();
Estos fragmentos funcionan correctamente. Cada fragmento se adjunta a la actividad y se guarda en la pila posterior sin ningún problema.
Entonces, cuando inicio A
, C
y luego B
, la pila se ve así:
| |
|B|
|C|
|A|
___
Y cuando presiono el botón 'atrás', B
se destruye y C
se reanuda.
Pero, cuando lanzo el fragmento A
por segunda vez, en lugar de reanudar desde la pila posterior, se agrega en la parte superior de la pila posterior
| |
|A|
|C|
|A|
___
Pero quiero reanudar A
y destruir todos los fragmentos encima (si los hay). En realidad, me gusta el comportamiento predeterminado de la pila de respaldo.
¿Cómo logro esto?
Esperado: ( A
debe reanudarse y los fragmentos superiores deben destruirse)
| |
| |
| |
|A|
___
Editar: (sugerido por A - C)
Este es mi código de prueba:
private void selectItem(int position) {
Fragment problemSearch = null, problemStatistics = null;
FragmentManager manager = getSupportFragmentManager();
FragmentTransaction ft = manager.beginTransaction();
String backStateName = null;
Fragment fragmentName = null;
boolean fragmentPopped = false;
switch (position) {
case 0:
fragmentName = profile;
break;
case 1:
fragmentName = submissionStatistics;
break;
case 2:
fragmentName = solvedProblemLevel;
break;
case 3:
fragmentName = latestSubmissions;
break;
case 4:
fragmentName = CPExercise;
break;
case 5:
Bundle bundle = new Bundle();
bundle.putInt("problem_no", problemNo);
problemSearch = new ProblemWebView();
problemSearch.setArguments(bundle);
fragmentName = problemSearch;
break;
case 6:
fragmentName = rankList;
break;
case 7:
fragmentName = liveSubmissions;
break;
case 8:
Bundle bundles = new Bundle();
bundles.putInt("problem_no", problemNo);
problemStatistics = new ProblemStatistics();
problemStatistics.setArguments(bundles);
fragmentName = problemStatistics;
default:
break;
}
backStateName = fragmentName.getClass().getName();
fragmentPopped = manager.popBackStackImmediate(backStateName, 0);
if (!fragmentPopped) {
ft.replace(R.id.content_frame, fragmentName);
}
ft.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_FADE);
ft.addToBackStack(backStateName);
ft.commit();
// I am using drawer layout
mDrawerList.setItemChecked(position, true);
setTitle(title[position]);
mDrawerLayout.closeDrawer(mDrawerList);
}
El problema es que cuando inicio A
y luego B
presiono 'atrás', B
se elimina y A
se reanuda. y presionar 'atrás' por segunda vez debería salir de la aplicación. Pero muestra una ventana en blanco y tengo que presionar hacia atrás una tercera vez para cerrarla.
Además, cuando inicio A
, luego B
, luego C
, luego B
otra vez ...
Esperado:
| |
| |
|B|
|A|
___
Real:
| |
|B|
|B|
|A|
___
¿Debo anular onBackPressed()
con alguna personalización o me falta algo?
fuente
OnBackstackChangedListener
para que pueda garantizar que está tratando con el Fragmento correcto.OnBackstackChangedListener
.instanceof
:)A-B-C-B
y presiona hacia atrás una vez, volveráA
y no volveráC
. Esto se debe a quepopBackStackImmediate
no solo aparece la etiqueta dada, sino también todo lo anterior. ¿Hay algún trabajo por ahí?Creo que este método puede resolver su problema:
que se publicó originalmente en esta pregunta
fuente
Paso 1: Implemente una interfaz con su clase de actividad
Paso 2: cuando llame al otro fragmento, agregue este método:
fuente
fuente
fuente
La solución más fácil cambiará esta línea
ft.replace(R.id.content_frame, A);
aft.add(R.id.content_frame, A);
Y dentro de su diseño XML, utilice
Clickable
significa que un dispositivo puntero puede hacer clic en él o un dispositivo táctil.Focusable
significa que puede obtener el foco de un dispositivo de entrada como un teclado. Los dispositivos de entrada como los teclados no pueden decidir a qué vista enviar sus eventos de entrada en función de las entradas en sí, por lo que los envían a la vista que tiene el foco.fuente