Je suis en train de créer une application pour Android (14 <= SDK <= 21) en utilisant une variable ActionBarActivity
et plusieurs Fragments
, telles que ListFragment
et MapFragment
, qui sont échangées dans une seule vue FrameLayout
.
ActionBarActivity remplace/valide automatiquement le fragment A. Lorsque l'utilisateur appuie sur un bouton, l'activité d'hébergement remplace/valide un nouveau fragment B. Mon objectif est de permettre à l'utilisateur de revenir sur le fragment A dès qu'elle appuie sur le bouton Précédent. .
Certains code maintenant.
Activité principale
public class MainActivity extends ActionBarActivity implements StopFragment.OnFragmentInteractionListener,
StopItemFragment.OnFragmentInteractionListener {
...
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
fragmentManager = getFragmentManager();
fragmentManager.enableDebugLogging(true);
...
if (fragmentManager.findFragmentById(R.id.content_frame) == null) {
StopItemFragment list = StopItemFragment.newInstance(null); //A - extends ListFragment
fragmentManager.beginTransaction()
.replace(R.id.content_frame, list)
.addToBackStack(null)
.commit();
}
...
@Override
public void onFragmentInteraction(String id) {
selectItem(Integer.parseInt(id));
}
private void selectItem(int position) {
StopFragment fragment = StopFragment.newInstance(null, null); //B - extends Fragment
...
fragmentManager.beginTransaction()
.replace(R.id.content_frame, fragment)
.commit();
...
}
}
Problème
Même si addToBackStack()
est appelé, lorsque je suis sur le fragment B, je ne peux pas revenir au fragment A. MainActivity est directement fermé . Pourtant, j’ai essayé de gérer la pile arrière sans succès. Je peux voir que le fragment est sur la pile, mais si j'appelle popBackStackImmediate()
, le fragment A est affiché et la transaction de fragment n'est pas effectuée. (première presse rien ne se passe, deuxième activité fermée)
J'attache également le logcat FragmentManager:
http://Pastebin.com/hFLHprL8
Pour ceux qui cherchent encore une solution.
Dans la classe principale Activity
(qui héberge les fragments), remplacez simplement onBackPressed()
.
@Override
public void onBackPressed() {
if (getFragmentManager().getBackStackEntryCount() > 0 ){
getFragmentManager().popBackStack();
} else {
super.onBackPressed();
}
}
Il n'y a pas de méthode onBackPressed()
dans le fragment, et cette méthode est juste pour le activity
. Ainsi, lorsque nous appuyons sur la touche Retour, le comportement par défaut de activity
est affiché, ce qui est
vous irez à l'activité précédente (s'il y en a une) ou à l'application va sortir.
Nous devons maintenant surcharger cette méthode pour indiquer à la activity
que lorsque nous appuierons sur la touche Précédent, s'il reste des fragments dans la pile arrière, les extraire (et c'est ici que la fonction addToBackStack()
apparaît). Sinon, suivez le comportement par défaut.
Essayez ceci (Remarque add pas remplacez pour fragmentA et addToBackStack () pour fragmentB)
StopItemFragment list = StopItemFragment.newInstance(null); //A - extends ListFragment
fragmentManager.beginTransaction()
.add(R.id.content_frame, list)
.commit();
et
StopFragment fragment = StopFragment.newInstance(null, null); //B - extends Fragment
...
fragmentManager.beginTransaction()
.replace(R.id.content_frame, fragment)
.addToBackStack("FragmentB")
.commit();
J'ai dû appeler beginTransaction()
et commit()
de FragmentManager
manuellement.
Résolu en surchargeant onBackPressed()
:
@Override
public void onBackPressed() {
...
if (fragmentManager.getBackStackEntryCount() > 1){
fragmentManager.popBackStackImmediate();
fragmentManager.beginTransaction().commit();
} else {
//handle finish
finish(); // Closes app
}
}
Si vous vous battez avec addToBackStack () & popBackStack (), utilisez simplement
FragmentTransaction ft =getSupportFragmentManager().beginTransaction();
ft.replace(R.id.content_frame, new HomeFragment(), "Home");
ft.commit();`
Dans votre activité dans OnBackPressed (), recherchez le segment par tag puis faites votre travail
Fragment home = getSupportFragmentManager().findFragmentByTag("Home");
if (home instanceof HomeFragment && home.isVisible()) {
// do you stuff
}
Pour plus d'informations https://github.com/DattaHujare/NavigationDrawer Je n'utilise jamais addToBackStack () pour gérer les fragments.
la raison pour laquelle les fonctions popBackStack()
et popBackStackImmediatly()
est due au fait que vous n'avez pas ajouté ce fragment (que vous souhaitez afficher) à la pile de sauvegarde. Pour ce faire, vous devez appeler addToBackStack () au moment de la transaction pour ajouter/remplacer votre fragment.