Terminare l'attività corrente da un frammento


96

Ho un frammento in un'attività che sto usando come cassetto di navigazione. Contiene pulsanti che, se cliccati, avviano nuove attività (startActivity da un frammento chiama semplicemente startActivity sull'attività corrente).

Per quanto mi riguarda, non riesco a capire come finirei l'attività corrente dopo averne iniziata una nuova.

Sto cercando di ottenere qualcosa di simile nel frammento:

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

Ma sembra che Fragment.class non implementa finish () (come implementa startActivity (...)).

Vorrei che il backstack delle attività venisse cancellato quando viene avviata la seconda attività. (quindi premere indietro dalla nuova attività tecnicamente li lascerebbe cadere di nuovo nel programma di avvio)

Risposte:


278

Quando si lavora con i frammenti, invece di usare thiso fare riferimento al contesto, usare sempre getActivity(). Dovresti chiamare

getActivity().finish();

per terminare la tua attività dal frammento.


12
getActivity()può essere nullin alcuni casi. Cosa dovremmo fare allora?
Matjaz Kristl

3
@ user983956 In questi casi l'attività è già distrutta, quindi non chiamare finish.
Cristian

2
Come suggerimento: getActivity può essere nullo se provi a usarlo prima di gonfiare la vista
csanonymus

1
L'attività dovrebbe essere il controller / incharge non il frammento, dovresti piuttosto richiamare l'attività tramite un'interfaccia di callback e lasciare che l'attività decida se deve finire da sola.
Ahmed

1
Inoltre, se hai singleton iniettati nell'attività, non dimenticare di distruggerli, creerà perdite di memoria o, se ci sono callback, rimuovili ad es. , se (getActivity ()! = null) {getActivity (). removeCallbacks (); getActivity (). destroy (); }
omersem

26

Beh in realtà ...

Non vorrei che il frammento tentasse di finire l'attività. Ciò conferisce troppa autorità al frammento, secondo me. Invece, userei la guida qui: http://developer.android.com/training/basics/fragments/communicating.html

Fare in modo che il frammento definisca un'interfaccia che l'attività deve implementare. Effettua una chiamata all'attività, quindi lascia che sia l'attività a decidere cosa fare con le informazioni. Se l'attività desidera terminare da sola, può farlo.


2
Questo è un buon punto, poiché una singola attività può avere più frammenti presenti. Come hai detto, il modo migliore per comunicare con un frammento alla sua attività è tramite un'interfaccia.
Sasquatch

11

Come accennato da Jon F Hancock , è così che un frammento può "chiudere" l'attività suggerendo che l'attività si chiuda. Questo rende il frammento portatile come è la ragione per loro. Se lo utilizzi in un'attività diversa, potresti non voler chiudere l'attività.

Il codice seguente è uno snippet di un'attività e un frammento che ha un pulsante di salvataggio e annullamento.

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, che contiene un'interfaccia che l'attività chiamante deve implementare.

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

1

Ogni volta che uso finish per chiudere il frammento, l'intera attività si chiude. Secondo i documenti, i frammenti dovrebbero rimanere finché rimane l'attività del genitore.

Invece, ho scoperto che posso cambiare le visualizzazioni dell'attività principale utilizzando questa istruzione: setContentView (R.layout.activity_main);

Questo mi riporta all'attività genitore.

Spero che questo aiuti qualcun altro che potrebbe essere alla ricerca di questo.


1

Molto semplice...

1- prendi semplicemente l'attività getActivity()nel frammento

2- poi chiama finish();

Quindi getActivity().finish();finirà solo l'attività del genitore.


1

È necessario utilizzare il metodo getActivity () per terminare l'attività dal frammento.

getActivity().finish();

1

In Fragment usa getActivity.finishAffinity ()

getActivity().finishAffinity();

Rimuoverà anche tutto il frammento che è stato spinto dall'attività corrente dallo Stack con l'attività ...


finishAffinity () rimuoverà tutte le attività che hanno la stessa affinità, quindi potrebbero essere terminate anche le attività al di sotto dell'attività corrente che contiene il frammento nello stack.
Zakaria M. Jawas

0

Prova questo. Non dovrebbe esserci alcun avviso ...

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

0

15 giugno 2020 - Risposta aggiornata.

Hai due opzioni per Java e Kotlin. Tuttavia, la logica di entrambi i modi è la stessa. Dovresti chiamare l' attività dopo la chiamata al metodo finish () .

Risposta per Kotlin ,

Se la tua attività non può essere nulla, utilizza la risposta_1 . Tuttavia, se la tua attività può essere nulla , utilizza la risposta_2 .

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

Risposta per Java,

getActivity().finish();

@canerkaseler


-1

prova a usare questo

Fragment.classnon implementafinish()

Quando si lavora con i frammenti, invece di usare questo o fare riferimento al contesto, usare sempre getActivity(). Dovresti chiamare


11
Dimmi la differenza tra la tua risposta e la prima risposta sopra (di @ coder_For_Life22) ...
Filipe Brito

non è una trappola
Demotivato il
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.