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.