Come chiudere il frammento corrente utilizzando Button come il pulsante Indietro?


89

Ho provato a chiudere il frammento corrente usando Imagebutton.

Sono in Fragment-A e si trasformerà in Fragment-B quando clicco sul pulsante.

E quando clicco sul pulsante in Fragment-B, si trasformerà in Fragment-C e chiuderà Fragment-B.

Se faccio clic sul pulsante Indietro in Fragment-C, tornerà al Fragment-A.

Il codice che ho provato è come il seguente

camera_album = (ImageButton) view.findViewById(R.id.camera_album);

camera_album.setOnClickListener(new Button.OnClickListener() {
    @Override
    public void onClick(View v) {

                    closefragment();
        Fragment fragment = FileBrowserFragment.newInstance(null, null, null) ;
        MainActivity.addFragment(LocalFileBrowserFragment.this, fragment) ;


    }
});

private void closefragment() {
    getActivity().getFragmentManager().beginTransaction().remove(this).commit();
}

Quando faccio clic sul pulsante Indietro in frammento-B, si trasforma in frammento-C.

Ma quando faccio clic sul pulsante Indietro su Fragment-C, non torna al Fragment-A. Torna allo sfondo vuoto. Se voglio tornare a Fragment-A, devo fare di nuovo clic sul pulsante Indietro.

Quindi, sembra non chiudere il frammento corrente completo.

Come finire il frammento corrente come il pulsante Indietro di Android?


Cos'è questo MainActivity.addFragment(LocalFileBrowserFragment.this, fragment)??. devi aggiungere il frammento al backstak e fare lo stesso pop di conseguenza
Raghunandan

È stato aggiunto il frammento nella funzione addFragment.
Wun

aggiungere frammento a cosa e un metodo di attività ??
Raghunandan

2
getActivity (). onBackPressed (); può farlo
Viswanath Lekshmanan

Risposte:


82

Dal frammento A, per passare a B, sostituire A con B e utilizzare addToBackstack()prima commit().

Ora dal frammento B, per andare a C, il primo utilizzo popBackStackImmediate(), questo riporterà A. Ora sostituisci A con C, proprio come la prima transazione.


4
per usinf popStackImmediate (): -> getView (). setOnKeyListener (new View.OnKeyListener () {@Override public boolean onKey (View v, int keyCode, KeyEvent event) {if (keyCode == KeyEvent.KEYCODE_BACK) {getActivity () .getSupportFragmentManager (). popBackStackImmediate (); return true;} return false;}});
Yash Agrawal,

134

Cambio il codice da getActivity().getFragmentManager().beginTransaction().remove(this).commit();

per

getActivity().getFragmentManager().popBackStack();

E può chiudere il frammento.


36
getActivity (). onBackPressed (); Questo farà quello che hai spiegato.
Viswanath Lekshmanan

5
@ suomi35 no. Quando è necessario eseguire l'override di onBackPressed (), dovrai affrontare problemi con tale realizzazione
Le_Enot

Non sembra funziona. nel 2016, in setNavigationOnClickListener non funziona.

1
@ViswanathLekshmanan Penso che questa dovrebbe essere una risposta invece di un commento. E la risposta accettata, inoltre.
Francisco Romero

1
Chiude anche l'attività! È richiesta solo la chiusura del frammento.
Zona

72

Per coloro che hanno bisogno di capire in modo semplice

Provare getActivity().onBackPressed();


getActivity () può essere null molte volte.
Arpit J.

1
@ArpitJ. è solo null prima che onAttach () venga chiamato, un frammento non può vivere senza un'attività.
Tamim Attafi

@TamimAttafi Vero, ma mi riferivo a casi come la rotazione o l'attività è terminata e per qualche motivo l'istanza del frammento è ancora lì, quindi restituirà null.
Arpit J.

popBackStack()e popBackStackImmediate()sono modi più diretti per far scoppiare il frammento più in alto senza simulare la pressione di un pulsante. Utilizzo di onBackPressed()trigger OnBackPressedCallbacks; se in futuro si desidera gestire specificamente le pressioni del pulsante Indietro, è necessario passare a popBackStack()/ popBackStackImmediate()per evitare di attivare i callback a livello di programmazione.
Nolan Amy

Inserisci questo codice nel metodo onclick dei pulsanti del frammento.
Anon

6

getActivity().onBackPressedfa tutto ciò di cui hai bisogno. Chiama automaticamente il metodo onBackPressed nell'attività principale.


5

Questo è un modo Kotlin per farlo, ho creato il pulsante nel layout dei frammenti e quindi ho impostato onClickListner in onViewCreated.

secondo il commento di @ Viswanath-Lekshmanan

override fun onViewCreated(view: View?, savedInstanceState: Bundle?) 
{
     super.onViewCreated(view, savedInstanceState)

     btn_FragSP_back.setOnClickListener {
        activity?.onBackPressed()
    }
}

questo chiude l'attività, non il frammento
nibbana

4

Prova questo:

ft.addToBackStack(null);   // ft is FragmentTransaction

Quindi, quando si preme il tasto Indietro , l'attività corrente (che contiene più frammenti) caricherà il frammento precedente anziché terminare se stessa.


4

Prova questo:

public void removeFragment(Fragment fragment){
    android.support.v4.app.FragmentManager fragmentManager = getSupportFragmentManager();
    android.support.v4.app.FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();

    fragmentTransaction.remove(fragment);
    fragmentTransaction.commit();
}

4

Puoi provare questa logica perché ha funzionato per me.

frag_profile profile_fragment = new frag_profile();

boolean flag = false;
@SuppressLint("ResourceType")
public void profile_Frag(){
    if (flag == false) {
        FragmentManager manager = getFragmentManager();
        FragmentTransaction transaction = manager.beginTransaction();
        manager.getBackStackEntryCount();
        transaction.setCustomAnimations(R.anim.transition_anim0, R.anim.transition_anim1);
        transaction.replace(R.id.parentPanel, profile_fragment, "FirstFragment");
        transaction.commit();
        flag = true;
    }

}

@Override
public void onBackPressed() {
    if (flag == true) {
        FragmentManager manager = getFragmentManager();
        FragmentTransaction transaction = manager.beginTransaction();
        manager.getBackStackEntryCount();
        transaction.remove(profile_fragment);
        transaction.commit();
        flag = false;
    }
    else super.onBackPressed();
}

3
Button ok= view.findViewById(R.id.btSettingOK);
Fragment me=this;
ok.setOnClickListener( new View.OnClickListener(){
    public void onClick(View v){
     getActivity().getFragmentManager().beginTransaction().remove(me).commit();
    }
});

3
Sebbene questo codice possa rispondere alla domanda, fornire un contesto aggiuntivo sul perché e / o come questo codice risponde alla domanda ne migliora il valore a lungo termine.
rollstuhlfahrer

1
Questo semplice codice rimuove effettivamente la visualizzazione frammento corrente tramite un pulsante OK o Chiudi su di essa. Lo uso per uscire da un pannello di impostazione della luce visualizzato come un frammento e tornare all'attività. Ci scusiamo per questo trucco ma con Android 8, penso non sia così pratico gestire più frammenti.
Bruno L.

1

Se devi gestire l'azione in modo più specifico con il pulsante Indietro, puoi utilizzare il seguente metodo:

view.setFocusableInTouchMode(true);
view.requestFocus();
view.setOnKeyListener(new View.OnKeyListener() {
    @Override
    public boolean onKey(View v, int keyCode, KeyEvent event) {
        if( keyCode == KeyEvent.KEYCODE_BACK )
        {
            onCloseFragment();
            return true;
        } else {
            return false;
        }
    }
});

0

Nei tuoi frammenti onCreateView(...)puoi rimuovere una vista chiamando container.removeView(view);. Quindi, se vuoi rimuovere il frammento, viewdovrebbe essere il valore restituito di onCreateView,

per esempio

    public View onCreateView(...){
        final View view = inflater.inflate(R.layout.your_fragments_layout,container,false);
        //Do something
        finishButton.setOnClickListener(new View.OnClickListener(){
            @Override
            public void onClick(View v){
                container.removeView(view);
            }
        });
        return view;
    }

0

se necessario nel 2020

    Objects.requireNonNull(getActivity()).onBackPressed();

-8

Prova questo

getActivity().finish();

1
Prova a spiegare di più la tua risposta, in modo che sia facile per OP e altre persone capire la risposta che torneranno a questa domanda in futuro
Aman Chhabra

7
questo chiude l'intera attività, non il frammento
busuu

Mi ha aiutato. Chi desidera maggiori informazioni può cercarlo su Google. Non c'è bisogno di copiare e incollare qui la documentazione ufficiale.
Alesha170

Se stai usando BottomNavigationView che di solito ha un'attività, questo comando chiuderà l'app invece di tornare al frammento precedente.
Aliton Oliveira,
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.