Terminando la actividad actual de un fragmento

96

Tengo un fragmento en una actividad que estoy usando como cajón de navegación. Contiene botones que, cuando se hace clic en ellos, inician nuevas actividades (startActivity de un fragmento simplemente llama a startActivity en la actividad actual).

Por mi vida, parece que no puedo entender cómo terminaría la actividad actual después de comenzar una nueva.

Estoy buscando lograr algo como esto en el fragmento:

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

Pero parece que Fragment.class no implementa finish () (como si implementa startActivity (...)).

Me gustaría que el backstack de la actividad se borre cuando inicien la segunda actividad. (por lo que presionar hacia atrás desde la nueva actividad técnicamente los devolvería al lanzador)

NPike
fuente

Respuestas:

277

Cuando trabaje con fragmentos, en lugar de usar thiso hacer referencia al contexto, use siempre getActivity(). Deberías llamar

getActivity().finish();

para terminar su actividad desde el fragmento.

coder_For_Life22
fuente
12
getActivity()puede ser nullen algunos casos. ¿Qué debemos hacer entonces?
Matjaz Kristl
3
@ user983956 En tales casos, la actividad ya está destruida, así que no llame finish.
Cristian
2
Como consejo: getActivity puede ser nulo si intenta usarlo antes de inflar la vista
csanonymus
1
La actividad debe ser el controlador / carga, no el fragmento, debería devolver la actividad a través de una interfaz de devolución de llamada y dejar que la actividad decida si debe terminar por sí misma.
Ahmed
1
Además, si tiene singletons inyectados en la actividad, no olvide destruirlos, esto creará pérdidas de memoria, o si hay devoluciones de llamada elimínelos, es decir. , if (getActivity ()! = null) {getActivity (). removeCallbacks (); getActivity (). destroy (); }
omersem
26

Bueno en realidad...

No permitiría que el Fragmento intente terminar la Actividad. Eso pone demasiada autoridad en el Fragmento en mi opinión. En su lugar, usaría la guía aquí: http://developer.android.com/training/basics/fragments/communicating.html

Haga que el Fragmento defina una interfaz que la Actividad debe implementar. Haga una llamada a la actividad, luego deje que la actividad decida qué hacer con la información. Si la actividad desea terminar sola, puede hacerlo.

Jon F Hancock
fuente
2
Ese es un buen punto, ya que una sola actividad puede tener múltiples fragmentos presentes. Como mencionas, la forma preferida para que un fragmento se comunique con su actividad es a través de una interfaz.
Sasquatch
11

Como lo mencionó Jon F Hancock , así es como un fragmento puede "cerrar" la actividad sugiriendo que la actividad se cierre. Esto hace que el fragmento sea portátil como es el motivo de ellos. Si lo usa en una actividad diferente, es posible que no desee cerrar la actividad.

El siguiente código es un fragmento de una actividad y un fragmento que tiene un botón para guardar y cancelar.

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, que contiene una interfaz que la actividad de llamada necesita implementar.

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
fuente
1

Cada vez que uso terminar para cerrar el fragmento, se cierra toda la actividad. Según los documentos, los fragmentos deben permanecer mientras permanezca la actividad principal.

En cambio, descubrí que puedo cambiar las vistas de la actividad principal usando esta declaración: setContentView (R.layout.activity_main);

Esto me devuelve a la actividad principal.

Espero que esto ayude a alguien más que pueda estar buscando esto.

Dave Cox
fuente
1

Muy simple...

1- solo toma actividad getActivity()en el fragmento

2- luego llama finish();

Así que acaba de getActivity().finish();terminar la actividad de los padres.

Ali Nawaz
fuente
1

Debe utilizar el método getActivity () para finalizar la actividad del fragmento.

getActivity().finish();
Madhu Jayarama
fuente
1

En Fragmento use getActivity.finishAffinity ()

getActivity().finishAffinity();

También eliminará todo el fragmento que empujó la actividad actual de la pila con la actividad ...

Tousif Akram
fuente
finishAffinity () eliminará todas las actividades que tengan la misma afinidad, por lo que las actividades por debajo de la actividad actual que contiene el fragmento en la pila también podrían finalizar.
Zakaria M. Jawas
0

Prueba esto. No debería haber ninguna advertencia ...

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

15 de junio de 2020 - Respuesta actualizada.

Tiene dos opciones para Java y Kotlin. Sin embargo, la lógica de ambas formas es la misma. Debería llamar a la actividad después de llamar al método finish () .

Respuesta de Kotlin ,

Si su actividad no puede ser nula, use Answer_1 . Sin embargo, si su actividad puede ser nula , use Answer_2 .

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

Respuesta para Java,

getActivity().finish();

@canerkaseler

canerkaseler
fuente
-1

intenta usar esto

si Fragment.classno implementafinish()

Cuando trabaje con fragmentos, en lugar de usar esto o hacer referencia al contexto, use siempre getActivity(). Deberías llamar

Rahul Goswami
fuente
11
Dime la diferencia entre tu respuesta y la primera respuesta anterior (por @ coder_For_Life22) ...
Filipe Brito
no es una trampa
Desmotivado el