166 votes

Comment reprendre un fragment existant depuis BackStack ?

J'apprends à utiliser les fragments. J'ai trois instances de Fragment qui sont initialisés en haut de la classe. J'ajoute le fragment à une activité comme ceci :

Déclarer et initialiser :

Fragment A = new AFragment();
Fragment B = new BFragment();
Fragment C = new CFragment();

Remplacement/Ajout :

FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
ft.replace(R.id.content_frame, A);
ft.addToBackStack(null);
ft.commit();

Ces extraits fonctionnent correctement. Chaque fragment est attaché à l'activité, et est sauvegardé dans la pile arrière sans aucun problème.

Donc quand je lance A , C et ensuite B la pile ressemble à ceci :

| |
|B|
|C|
|A|
___

Et quand j'appuie sur le bouton "retour", B est détruit et C est repris.

Mais, quand je lance le fragment A une deuxième fois, au lieu de reprendre à partir de la pile arrière, il est ajouté au sommet de la pile arrière

| |
|A|
|C|
|A|
___

Mais je veux reprendre A et détruire tous les fragments qui se trouvent au-dessus (s'il y en a). En fait, j'aime juste le comportement par défaut de la pile arrière.

Comment puis-je y parvenir ?

Attendu : ( A doit être repris et les fragments supérieurs doivent être détruits)

| |
| |
| |
|A|
___

Edit : (suggéré par A--C)

Voici mon code d'essai :

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);
    }

Le problème est que, lorsque je lance A et ensuite B puis appuyez sur "retour", B est supprimé et A Le fait d'appuyer une seconde fois sur la touche "retour" permet de quitter l'application. Mais elle affiche une fenêtre vide et je dois appuyer une troisième fois sur "retour" pour la fermer.

Aussi, quand je lance A alors B alors C alors B encore...

Attendu :

| |
| |
|B|
|A|
___

Réel :

| |
|B|
|B|
|A|
___

Dois-je passer outre onBackPressed() avec une quelconque personnalisation ou est-ce que je rate quelque chose ?

0voto

Hossam Hassan Points 387

La solution la plus simple sera de changer cette ligne

ft.replace(R.id.content_frame, A); a ft.add(R.id.content_frame, A);

Et dans votre mise en page XML, veuillez utiliser

  android:background="@color/white"
  android:clickable="true"
  android:focusable="true"

Clickable signifie qu'il peut être cliqué par un dispositif de pointage ou tapé par un dispositif tactile.

Focusable signifie qu'il peut obtenir le focus à partir d'un périphérique d'entrée comme un clavier. Les périphériques d'entrée comme les claviers ne peuvent pas décider à quelle vue envoyer ses événements d'entrée sur la base des entrées elles-mêmes, ils les envoient donc à la vue qui a le focus.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X