web-dev-qa-db-fra.com

comment revenir au fragment précédent en appuyant manuellement sur le bouton de retour de fragment individuel?

J'ai seulement une activity et plusieurs fragments dans ma candidature.

Deux fragments principaux A(left) et B (à droite).

Fragment A1 called from A

B1 called from B

B2 called from B1

Tous les fragments ont des boutons individuels.

Ainsi, lorsque j'appuie sur le bouton retour de fragment A1 , il devrait revenir àA, de même lorsque le bouton Retour de B2 est enfoncé, B1 apparaît et à partir de B1 àBet ainsi de suite.

Comment implémenter ce type de fonctionnalité?

24
Mihir Shah
public void onBackPressed()
{
    FragmentManager fm = getActivity().getSupportFragmentManager();
    fm.popBackStack();
}
31
Manitoba

J'ai mis en œuvre le scénario similaire tout à l'heure. 

L'activité 'A' -> appelle un fragment 'A1' et clique sur l'élément de menu pour appeler le fragment 'A2'. Si l'utilisateur appuie sur le bouton précédent de 'A2', il retourne à 'A1' et si l'utilisateur appuie sur De retour de 'A1' après cela, il termine l'activité 'A' et revient.

Voir le code suivant:

Activité 'A' - Méthode OnCreate ():

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activityA);

    if (savedInstanceState == null) {
        Fragment fragInstance;

        //Calling the Fragment newInstance Static method
        fragInstance = FragmentA1.newInstance();

        getFragmentManager().beginTransaction()
                .add(R.id.container, fragInstance)
                .commit();
    }
}

Fragment: 'A1'

Je remplace le fragment existant par le nouveau fragment lorsque l'action de clic sur l'élément de menu se produit:

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    if (item.getItemId() == R.id.action_edit_columns) {
        //Open the Fragment A2 and add this to backstack
        Fragment fragment = FragmentA2.newInstance();
        this.getFragmentManager().beginTransaction()
                .replace(R.id.container, fragment)
                .addToBackStack(null)
                .commit();

        return true;
    }
    return super.onOptionsItemSelected(item);
}

Activité 'A' - Méthode onBackPressed ():

Étant donné que tous les fragments ont une activité parente ("A"), la méthode onBackPressed () vous permet de supprimer des fragments s'il en existe ou de revenir à l'activité précédente.

@Override
public void onBackPressed() {
    if(getFragmentManager().getBackStackEntryCount() == 0) {
        super.onBackPressed();
    }
    else {
        getFragmentManager().popBackStack();
    }
}

Si vous recherchez des fragments d'inclusion dans des fragments, veuillez vous reporter au lien: http://developer.Android.com/about/versions/Android-4.2.html#NestedFragments

23
TrueBlue

La réponse de @ trueblue m'a donné raison, avec un problème mineur mais ennuyeux. Lorsqu'il n'y a qu'un seul fragment sur le backstack et que vous appuyez sur le bouton Précédent, ce cadre est supprimé et l'application reste active avec un écran vide. L'utilisateur devait appuyer sur le bouton de retour une fois de plus pour quitter l'application. J'ai modifié le code original en suivant afin de gérer cette situation

@Override
public void onBackPressed() {
    if(getFragmentManager().getBackStackEntryCount() == 0) {
        super.onBackPressed();
    }
    else if(getFragmentManager().getBackStackEntryCount() == 1) {
        moveTaskToBack(false);
    }
    else {
        getFragmentManager().popBackStack();
    }
}

Lorsqu'il n'y a qu'un seul fragment dans le backstack, nous disons essentiellement à Android de déplacer l'ensemble de l'application vers l'arrière. 

Mise à jour (et probablement une meilleure réponse)

Ainsi, après avoir lu un peu plus à ce sujet, j'ai découvert que vous pouvez ajouter des transactions de gestionnaire de fragments à la pile puis Android traite les presses à l'envers automatiquement et de la manière souhaitée. L'extrait de code ci-dessous montre comment faire cela.

Fragment fragment; //Create and instance of your fragment class here
FragmentManager fragmentManager = getFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();

fragmentTransaction.replace(R.id.fragment_container, fragment).addToBackStack(null);
fragmentTransaction.commit();
fragmentTransaction.addToBackStack(null);

La dernière ligne montre comment vous ajoutez une transaction pour sauvegarder la pile. Cela résout les problèmes de presse pour les fragments dans la plupart des situations, sauf une. Si vous continuez d'appuyer sur le bouton Précédent, vous finirez par atteindre un point où il n'y a qu'un seul fragment dans la pile arrière. À ce stade, vous voudrez faire l’une des deux choses suivantes:

  1. Supprimez l'activité contenant le fragment de la pile arrière de la tâche dans laquelle l'activité est en cours d'exécution. C'est parce que vous ne voulez pas vous retrouver avec une activité vide
  2. Si l'activité est la seule activité dans la pile arrière de la tâche, placez la tâche en arrière-plan. 

Dans mon cas, c'était la dernière, alors j'ai modifié la méthode onBackPressed surchargée de ma réponse précédente pour qu'elle ressemble à celle ci-dessous

@Override
public void onBackPressed() {
    if(getFragmentManager().getBackStackEntryCount() == 1) {
        moveTaskToBack(false);
    }
    else {
        super.onBackPressed();
    }
}

Ce code est plus simple car il comporte moins de logique et repose sur un framework que sur notre code personnalisé. Malheureusement, je n'ai pas réussi à implémenter le code pour la première situation car je n'en avais pas besoin.

13
Suhas

Juste faire

getActivity().getFragmentManager().popBackStack();
4
user4853635

Vous devez implémenter votre propre implémentation de backstack comme expliqué ici.

Vous pouvez appeler la popFragments() chaque fois que vous cliquez sur le bouton de retour dans un fragment et appeler pushFragments() chaque fois que vous naviguez d'un fragment à l'autre.

4
TNR

Essayez ceci, son travail pour moi.

public void onBackPressed() {
    if (mainLayout.isMenuShown()) {
        mainLayout.toggleMenu();
    } else {
        FragmentManager fm = getSupportFragmentManager();
        Log.print("back stack entry", fm.getBackStackEntryCount() + "");

        if (fm.getBackStackEntryCount() > 1) {
            fm.popBackStack();
            // super.onBackPressed();
            // return;
        } else {
            if (doubleBackToExitPressedOnce) {
                fm.popBackStack();
                super.onBackPressed();
                return;
            }

            this.doubleBackToExitPressedOnce = true;
            Toast.makeText(this, "Press one more time to exit",
                    Toast.LENGTH_SHORT).show();

            new Handler().postDelayed(new Runnable() {

                @Override
                public void run() {

                    doubleBackToExitPressedOnce = false;
                }
            }, 3000);

        }
    }
}
1
Shreyans Patel

Le bouton Précédent traversera dans l'ordre dans lequel les fragments ont été ajoutés à backstack . Ceci est fourni en tant que fonction de navigation par défaut. Maintenant, si vous voulez aller à un fragment spécifique, vous pouvez le montrer de backstack.

0
S.D.

Vous pouvez le gérer en ajoutant une balise dans la backStack. Vérifiez ma réponse ici: 

https://stackoverflow.com/a/19477957/1572408

j'espère que ça aide 

0
Rudi