Fin de l'activité en cours à partir d'un fragment

96

J'ai un fragment dans une activité que j'utilise comme tiroir de navigation. Il contient des boutons qui, lorsqu'on clique dessus, démarrent de nouvelles activités (startActivity à partir d'un fragment appelle simplement startActivity sur l'activité en cours).

Pour la vie de moi, je n'arrive pas à comprendre comment je finirais l'activité actuelle après en avoir commencé une nouvelle.

Je cherche à réaliser quelque chose comme ça dans le fragment:

@Override
public void onClick(View view) {
    // TODO Auto-generated method stub
    if (view == mButtonShows) {
        Intent intent = new Intent(view.getContext(), MyNewActivity.class);
        intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
        startActivity(intent);
        finish();
    } 
}

Mais il semble que Fragment.class n'implémente pas finish () (comme il implémente startActivity (...)).

Je souhaite que la backstack d'activité soit effacée lors du lancement de la 2ème activité. (Donc, repousser la nouvelle activité les ramènerait techniquement dans le lanceur)

NPike
la source

Réponses:

278

Lorsque vous travaillez avec des fragments, au lieu d'utiliser thisou de faire référence au contexte, utilisez toujours getActivity(). Tu devrais appeler

getActivity().finish();

pour terminer votre activité de fragment.

coder_For_Life22
la source
12
getActivity()peut être nulldans certains cas. Que devrions-nous faire alors?
Matjaz Kristl
3
@ user983956 Dans de tels cas, l'activité est déjà détruite, alors n'appelez pas finish.
Cristian
2
En guise de conseil: getActivity peut être nul si vous essayez de l'utiliser avant de gonfler la vue
csanonymus
1
L'activité doit être le contrôleur / charge et non le fragment, vous devez plutôt rappeler l'activité via une interface de rappel et laisser l'activité décider si elle doit se terminer d'elle-même.
Ahmed
1
Aussi, si vous avez des singletons injectés dans l'activité, n'oubliez pas de les détruire, cela créera des fuites de mémoire, ou s'il y a des callbacks supprimez-les ie. , if (getActivity ()! = null) {getActivity (). removeCallbacks (); getActivity (). destroy (); }
omersem
26

Eh bien en fait ...

Je ne voudrais pas que le fragment essaie de terminer l'activité. Cela place trop d'autorité sur le Fragment à mon avis. Au lieu de cela, j'utiliserais le guide ici: http://developer.android.com/training/basics/fragments/communicating.html

Demandez au fragment de définir une interface que l'activité doit implémenter. Appelez l'activité, puis laissez l'activité décider quoi faire des informations. Si l'activité souhaite se terminer, elle le peut.

Jon F Hancock
la source
2
C'est un bon point, car une seule activité peut avoir plusieurs fragments présents. Comme vous l'avez mentionné, le moyen préféré pour un fragment de communiquer à son activité est via une interface.
Sasquatch
11

Comme mentionné par Jon F Hancock , c'est ainsi qu'un fragment peut «fermer» l'activité en suggérant la fermeture de l'activité. Cela rend le fragment portable comme c'est la raison pour eux. Si vous l'utilisez dans une autre activité, vous ne voudrez peut-être pas fermer l'activité.

Le code ci-dessous est un extrait d'une activité et d'un fragment qui a un bouton d'enregistrement et d'annulation.

PlayerActivity

public class PlayerActivity extends Activity 
    implements PlayerInfo.PlayerAddListener {

    public void onPlayerCancel() {
       // Decide if its suitable to close the activity, 
       //e.g. is an edit being done in one of the other fragments?
       finish();
    }
}

PlayerInfoFragment, qui contient une interface que l'activité appelante doit implémenter.

public class PlayerInfoFragment extends Fragment {
   private PlayerAddListener callback; // implemented in the Activity

   @Override
   public void onAttach(Activity activity) {
     super.onAttach(activity);
     callback= (PlayerAddListener) activity;
   }

   public interface PlayerAddListener {
       public void onPlayerSave(Player p); // not shown in impl above
       public void onPlayerCancel();
   }

   public void btnCancel(View v) {
      callback.onPlayerCancel(); // the activity's implementation
   }
}
Sasquatch
la source
1

Chaque fois que j'utilise la finition pour fermer le fragment, toute l'activité se ferme. Selon la documentation, les fragments doivent rester aussi longtemps que l'activité parent persiste.

Au lieu de cela, j'ai trouvé que je pouvais modifier les vues de l'activité parente en utilisant cette instruction: setContentView (R.layout.activity_main);

Cela me ramène à l'activité des parents.

J'espère que cela aidera quelqu'un d'autre qui pourrait le rechercher.

Dave Cox
la source
1

Très simple...

1- il suffit de saisir l'activité getActivity()dans le fragment

2- puis appelez finish();

Alors getActivity().finish();va juste terminer l'activité des parents.

Ali Nawaz
la source
1

Vous devez utiliser la méthode getActivity () pour terminer l'activité à partir du fragment.

getActivity().finish();
Madhu Jayarama
la source
1

Dans Fragment, utilisez getActivity.finishAffinity ()

getActivity().finishAffinity();

Cela supprimera également tous les fragments poussés par l'activité actuelle de la pile avec l'activité ...

Tousif Akram
la source
finishAffinity () supprimera toutes les activités qui ont la même affinité, donc les activités en dessous de l'activité actuelle qui contient le fragment dans la pile pourraient également être terminées.
Zakaria M. Jawas
0

Essaye ça. Il ne devrait y avoir aucun avertissement ...

            Activity thisActivity = getActivity();
            if (thisActivity != null) {
                startActivity(new Intent(thisActivity, yourActivity.class)); // if needed
                thisActivity.finish();
            }
octet sam
la source
0

15 juin 2020 - Réponse mise à jour.

Vous avez deux options pour Java et Kotlin. Cependant, la logique des deux manières est la même. Vous devez appeler activité après avoir appelé la méthode finish () .

Réponse pour Kotlin ,

Si votre activité ne peut pas être nulle, utilisez Answer_1 . Cependant, si votre activité peut être nulle , utilisez Answer_2 .

Answer_1: activity!!.finish()
Answer_2: activity?.finish()

Réponse pour Java,

getActivity().finish();

@canerkaseler

canerkaseler
la source
-1

essayez d'utiliser ceci

oui Fragment.classne met pas en œuvrefinish()

Lorsque vous travaillez avec des fragments, au lieu de l'utiliser ou de vous référer au contexte, utilisez toujours getActivity(). Tu devrais appeler

Rahul Goswami
la source
11
Dites-moi la différence entre votre réponse et la première réponse ci-dessus (par @ coder_For_Life22) ...
Filipe Brito
dont c'est un piège
Démotivé