web-dev-qa-db-fra.com

Tiroir de navigation, manipulant le bouton de retour pour revenir aux fragments précédents?

J'utilise le tiroir de navigation intégré pour exécuter mon application. Je n'arrive pas à comprendre comment gérer le bouton de retour. Quand il est pressé, je veux qu'il charge à nouveau le tout premier fragment. Fragment 1.

Ainsi, lorsque l'application se lance, vous voyez Fragment1 lancé. Ils peuvent ensuite cliquer sur le fragment 2-5 pour accéder à d'autres pages. Dans toutes ces pages, je veux que le bouton de retour ramène l'utilisateur à Fragment1. Le seul endroit où l'utilisateur devrait pouvoir quitter l'application via le bouton de retour est Fragment1.

Depuis que tout est géré par une FragmentActivity, j'ai essayé de jouer avec le bouton arrière là-bas. Je continue cependant d'obtenir une erreur de fermeture forcée:

(01-11 14:09:33.114: E/AndroidRuntime(8292): Android.view.InflateException: Binary XML file line #7: Error inflating class fragment)

Voici ce que j'ai jusqu'à présent:

Je me suis assuré d'ajouter les fragments à la pile arrière comme ceci:

fm.beginTransaction().replace(R.id.main, newFragment).addToBackStack("fragBack").commit();

Bouton retour:

@Override
public void onBackPressed() {
    if (getSupportFragmentManager().findFragmentByTag("fragBack") != null) {

    }
    else {
        super.onBackPressed();
        return;
    }
    if (getSupportFragmentManager().getBackStackEntryCount() != 0) {
        Toast.makeText(getApplicationContext(), "Test", Toast.LENGTH_LONG).show();
        Fragment frag = getSupportFragmentManager().findFragmentByTag("fragBack");
        FragmentTransaction transac = getSupportFragmentManager().beginTransaction().remove(frag);
                transac.commit();
    }

}

Quelqu'un sait-il ce que je dois faire? Dois-je appeler onBackPressed dans chaque fragment (si c'est même possible) plutôt que dans FragmentActivity qui contrôle le tiroir? Dans mes anciennes applications, le bouton retour fermait bien, quel que soit le fragment sur lequel l'utilisateur se trouvait, mais celui que je crée maintenant, je veux que le bouton retour revienne à Fragment1.

J'apprécierais vraiment de l'aide, merci.

onItemClick

@Override
        public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {

            Fragment newFragment = new MapsPage();
            FragmentManager fm = getSupportFragmentManager();
            switch(i) {
            case 0:
                newFragment = new Fragment2();
                break;
            case 1:
                newFragment = new Fragment3();
                break;
            case 2:
                newFragment = new Fragment4();
                break;
            case 3:
                newFragment = new Fragment5();
                break;
            }
            fm.beginTransaction().add(R.id.main, newFragment).addToBackStack("fragback").commit();
            drawerLayout.closeDrawer(rl);
        }
33
RED_

Au lieu de:

fm.beginTransaction().replace(R.id.main, newFragment).addToBackStack("fragBack").commit();

Appel:

fm.beginTransaction().add(R.id.main, newFragment).addToBackStack("fragBack").commit();

addToBackStack fonctionne avec add.

La fonction replace supprime le fragment précédent et place un nouveau fragment, donc sur votre back-stack il n'y a qu'un seul fragment tout le temps. Utilisez donc la fonction add pour conserver les fragments précédents sur la pile.

Pour toujours obtenir fragemnt1 à partir de n'importe quel fragment surBackPress, essayez de faire ce qui suit:

getFragmentManager().popBackStack();
fm.beginTransaction().add(R.id.main, newFragment).addToBackStack("fragBack").commit();

cela supprimera la dernière transaction du backstack et en ajoutera une nouvelle. Essaye ça.

36
vipul mittal

Je voulais juste faire part de mes constatations même si cette question est un peu ancienne pour quiconque aurait pu avoir le même problème avec la réponse acceptée. Pour moi, en faisant la méthode suggérée dans la réponse acceptée, les couches se chevauchaient, ce qui les rend rapidement illisibles. Le code ci-dessous (adapté de la réponse acceptée) évite la superposition mais ajoute toujours l'écran à la pile arrière.

fragmentManager.beginTransaction().replace(R.id.container, fragment).addToBackStack("fragBack").commit();

J'espère que cela aide quelqu'un!

6
Kyle

dans certains cas, vous devez utiliser replace alors vous ne pouvez pas travailler avec addtobackstack () afin que vous puissiez utiliser ce code dans mainActivity. dans ce code lorsque vous appuyez sur la touche retour, vous accédez toujours au premier fragment (je l'appelle HomeFragment) et lorsque vous êtes dans Home Fragment, il vous faut deux fois le temps de sortir de l'application (désolé pour mon pauvre anglais)

 private Boolean exit = false;
@Override
    public void onBackPressed() {
        if (exit) {
            super.onBackPressed();
            return;
        }

    try {
        FragmentManager fragmentManager = getSupportFragmentManager();
        Fragment fragment = fragmentManager.findFragmentByTag("HOME");
        if (fragment != null) {
            if (fragment.isVisible()) {
                this.exit = true;
                Toast.makeText(this, "Press Back again to Exit", Toast.LENGTH_SHORT).show();
            }
        }
        else {
            fragment = HomeFragment.class.newInstance();
            getFragmentManager().popBackStack();
            fragmentManager.beginTransaction().replace(R.id.flContent, fragment, "HOME").commit();
        }
    } catch (Exception e) {

    }
    new Handler().postDelayed(new Runnable() {
        @Override
        public void run() {
            exit = false;
        }
    }, 2000);
}
3
Muzhan
 - @Override
       public void onBackPressed() {
           DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
           int backstack = getSupportFragmentManager().getBackStackEntryCount();
           if (drawer.isDrawerOpen(GravityCompat.START)) {
               drawer.closeDrawer(GravityCompat.START);
           } else if (backstack > 0) {
              for (int i = 0; i < backstack; i++) {
                   getSupportFragmentManager().popBackStackImmediate();
            }
       } else {
           this.finish();
        }
    }
1
Neeraj Gupta