¿Cómo cerrar el fragmento actual usando Button como el botón Atrás?

85

Intenté cerrar el fragmento actual usando Imagebutton.

Estoy en el Fragmento-A y se convertirá en el Fragmento-B cuando haga clic en el botón.

Y cuando hago clic en el botón en Fragmento-B, cambiará al Fragmento-C y cerrará el Fragmento-B.

Si hago clic en el botón Atrás en Fragmento-C, volverá al Fragmento-A.

El código que he probado es como el siguiente

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

Cuando hago clic en el botón Atrás en el fragmento B, se convierte en el Fragmento-C.

Pero cuando hago clic en el botón Atrás en Fragmento-C, no vuelve al Fragmento-A. Vuelve al fondo vacío. Si quiero volver al Fragmento-A, tengo que hacer clic en el botón Atrás una vez más.

Entonces, parece que no cierra el fragmento actual por completo.

¿Cómo terminar el fragmento actual como el botón de retroceso de Android?

Wun
fuente
¿Qué es esto MainActivity.addFragment(LocalFileBrowserFragment.this, fragment)? debe agregar el fragmento a backstak y hacer estallar el mismo en consecuencia
Raghunandan
Se ha agregado el fragmento en la función addFragment.
Wun
agregar fragmento a qué y un método de actividad?
Raghunandan
2
getActivity (). onBackPressed (); puede hacer esto
Viswanath Lekshmanan

Respuestas:

82

Desde el Fragmento A, para ir a B, reemplace A con B y use addToBackstack()antes commit().

Ahora, desde el Fragmento B, para ir a C, primer uso popBackStackImmediate(), esto traerá de vuelta A. Ahora reemplace A con C, al igual que la primera transacción.

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

Cambio el código de getActivity().getFragmentManager().beginTransaction().remove(this).commit();

a

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

Y puede cerrar el fragmento.

Wun
fuente
35
getActivity (). onBackPressed (); Cree que esto hará lo que ha explicado.
Viswanath Lekshmanan
4
@ suomi35 no. Cuando necesite anular onBackPressed (), enfrentará problemas con tal realización
Le_Enot
No parece que funcione. en 2016, en setNavigationOnClickListener no funciona.
1
@ViswanathLekshmanan Creo que esto debería ser una respuesta en lugar de un comentario. Y la respuesta aceptada, además.
Francisco Romero
1
¡También cierra la Actividad! Solo se requiere el cierre de fragmentos.
Zona
70

Para aquellos que necesitan descubrir una forma sencilla

Tratar getActivity().onBackPressed();

Viswanath Lekshmanan
fuente
getActivity () puede ser nulo muchas veces.
Arpit J.
1
@ArpitJ. solo es nulo antes de que se llame a onAttach (), un fragmento no puede vivir sin una actividad.
Tamim Attafi
@TamimAttafi Verdadero, pero me refería a casos como la rotación o la actividad finalizada y, por alguna razón, la instancia del fragmento todavía está allí, entonces devolverá nulo.
Arpit J.
popBackStack()y popBackStackImmediate()son formas más directas de hacer estallar el fragmento superior sin simular la presión de un botón. Usando onBackPressed()disparadores OnBackPressedCallbacks; Si en el futuro desea manejar específicamente las pulsaciones del botón Atrás, tendrá que cambiar a popBackStack()/ popBackStackImmediate()para evitar activar las devoluciones de llamada mediante programación.
Nolan Amy
Pones este código dentro del método onclick de los botones del Fragmento.
Anon
6

getActivity().onBackPressedhace todo lo que necesita. Llama automáticamente al método onBackPressed en la actividad principal.

Farruh Habibullaev
fuente
4

Prueba esto:

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

Entonces, cuando presiona la tecla de retroceso , la actividad actual (que contiene múltiples fragmentos) cargará el fragmento anterior en lugar de terminar por sí misma.

Shailendra Madda
fuente
4

Puedes probar esta lógica porque me funcionó.

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();
}
Rahul Rathore
fuente
4

Esta es una forma de Kotlin de hacer esto, he creado un botón en el diseño de fragmentos y luego configuré onClickListner en onViewCreated.

según el comentario de @ Viswanath-Lekshmanan

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

     btn_FragSP_back.setOnClickListener {
        activity?.onBackPressed()
    }
}
Abdul Rehman
fuente
esto cierra la actividad, no el fragmento
nibbana
3

Prueba esto:

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();
}
Ninguna
fuente
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();
    }
});
Bruno L.
fuente
3
Si bien este código puede responder a la pregunta, proporcionar un contexto adicional sobre por qué y / o cómo este código responde a la pregunta mejora su valor a largo plazo.
rollstuhlfahrer
Este código simple en realidad elimina la vista del fragmento actual con un botón Aceptar o Cerrar. Lo uso para salir de un panel de configuración de luz que se muestra como un Fragmento y volver a la Actividad. Perdón por este truco, pero en Android 8, creo que no es tan práctico administrar varios Fragmentos.
Bruno L.
1

Si necesita manejar la acción de manera más específica con el botón de retroceso, puede usar el siguiente método:

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;
        }
    }
});
Morteza Jalambadani
fuente
0

En sus Fragmentos onCreateView(...), puede eliminar una vista llamando container.removeView(view);. Entonces, si desea eliminar el fragmento, entonces viewdebería ser el valor de retorno de onCreateView,

por ejemplo

    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;
    }
Ilmard
fuente
-7

Prueba este

getActivity().finish();
Karan Chunara
fuente
1
Intente explicar más su respuesta, de modo que sea fácil para OP y otras personas entender la respuesta que vuelva a esta pregunta en el futuro
Aman Chhabra
7
esto cierra toda la actividad, no el fragmento
busuu
Me ayudó. Aquellos que quieran más información pueden buscarlo en Google. No es necesario copiar y pegar aquí la documentación oficial.
Alesha170
Si está utilizando BottomNavigationView, que generalmente tiene una actividad, este comando cerrará la aplicación en lugar de volver al fragmento anterior.
Aliton Oliveira