Tengo un fragmento múltiple dentro de una actividad. Al hacer clic en un botón, estoy comenzando un nuevo fragmento, agregándolo al backstack. Naturalmente, esperaba que se llamara al onPause()
método del Fragmento actual y al onResume()
nuevo Fragmento. Pues no está pasando.
LoginFragment.java
public class LoginFragment extends Fragment{
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
final View view = inflater.inflate(R.layout.login_fragment, container, false);
final FragmentManager mFragmentmanager = getFragmentManager();
Button btnHome = (Button)view.findViewById(R.id.home_btn);
btnHome.setOnClickListener(new View.OnClickListener() {
public void onClick(View view){
HomeFragment fragment = new HomeFragment();
FragmentTransaction ft2 = mFragmentmanager.beginTransaction();
ft2.setCustomAnimations(R.anim.slide_right, R.anim.slide_out_left
, R.anim.slide_left, R.anim.slide_out_right);
ft2.replace(R.id.middle_fragment, fragment);
ft2.addToBackStack("");
ft2.commit();
}
});
}
@Override
public void onResume() {
Log.e("DEBUG", "onResume of LoginFragment");
super.onResume();
}
@Override
public void onPause() {
Log.e("DEBUG", "OnPause of loginFragment");
super.onPause();
}
}
HomeFragment.java
public class HomeFragment extends Fragment{
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
final View view = inflater.inflate(R.layout.login_fragment, container, false);
}
@Override
public void onResume() {
Log.e("DEBUG", "onResume of HomeFragment");
super.onResume();
}
@Override
public void onPause() {
Log.e("DEBUG", "OnPause of HomeFragment");
super.onPause();
}
}
Lo que esperaba era
- Cuando se hace clic en el botón, LoginFragment se reemplaza con
HomeFragment ,
onPause()
de LoginFragment yonResume()
de HomeFragment se llama - Cuando se presiona la espalda, HomeFragment se poped y LoginFragment se ve, y
onPause()
de HomeFragment yonResume()
de LoginFragment se llama.
Lo que estoy obteniendo es
- Cuando se hace clic en el botón, HomeFragment reemplaza correctamente LoginFragment , se llama a onResume () de HomeFragment , pero nunca se llama a onPause () de LoginFragment .
- Cuando se vuelve a presionar, HomeFragment aparece correctamente para revelar LoginFragment , se llama a onPause () de HomeFragment , pero onResume () de LoginFragment nunca se llama.
¿Es este el comportamiento normal? ¿Por qué es onResume()
de LoginFragment no conseguir llama cuando se presiona el botón de retroceso.
android
android-fragments
onresume
back-stack
Krishnabhadra
fuente
fuente
Respuestas:
Los fragmentos
onResume()
oonPause()
serán llamados solo cuando se llamen las ActividadesonResume()
oonPause()
. Están estrechamente acoplados a laActivity
.Lea la sección Manejo del ciclo de vida del fragmento de este artículo .
fuente
onPause()
ser llamado después enonSaveInstanceState()
lugar de antes. Esto se puede reproducir si usted a un niño diferente en miFragmentStatePagerAdapter
(digamos que se mueve del niño 0 al niño 2, tenga en cuenta que esto sucede porque el niño 0 se destruye cuando se abre el niño 2 )ft2.replace()
,FragmentTransaction.remove()
se llama al método yLoginfragment
se eliminará. Consulte esto . Así queonStop()
deLoginFragment
será llamado en lugar deonPause()
. (Como el nuevo fragmento reemplaza completamente al antiguo).ft2.addtobackstack()
, el estado delLoginfragment
se guardará como un paquete y cuando haga clic en el botón Atrás desdeHomeFragment
,onViewStateRestored()
se llamará seguido deonStart()
deLoginFragment
. Entonces eventualmenteonResume()
no se llamará.fuente
onViewStateRestored
se llama si tienessetRetainInstance(true)
Aquí está mi versión más robusta de la respuesta de Gor (el uso de fragments.size () no es confiable debido a que el tamaño no se reduce después de que el fragmento aparece)
Y el método 'getCurrentTopFragment':
fuente
Si realmente desea reemplazar un fragmento dentro de otro fragmento, debe usar Fragmentos anidados .
En su código debe reemplazar
con
fuente
pero tenga cuidado si hay más de un fragmento visible
fuente
ViewPager
con fragmentos hará referencia a sus fragmentos).Tengo un código muy similar al tuyo y si funciona en Pause () y onResume (). Al cambiar el fragmento, estas funciones se activan respectivamente.
Código en fragmento:
Iniciar sesión cuando cambio de fragmento:
Fragmento de onCreateView:
Acción cuando vuelvo a pulsar (en la actividad donde cargo el fragmento):
fuente
Lo que hago en fragmento infantil:
Y luego anular onResume en ParentFragment
fuente
Simplemente no puede agregar un fragmento a un fragmento. Esto debe suceder en FragmentActivity. Supongo que está creando el LoginFragment en una FragmentActivity, por lo que para que esto funcione, debe agregar HomeFragment a través de FragmentActivity cuando se cierra el inicio de sesión.
El punto general es que necesita una clase FragmentActivity desde donde agrega cada Fragment al FragmentManager. No es posible hacer esto dentro de una clase Fragment.
fuente
Si agrega el fragmento en XML, no puede intercambiarlos dinámicamente. Lo que sucede es que son demasiado, por lo que los eventos no se disparan como cabría esperar. El problema está documentado en esta pregunta. Reemplazar FragmenManager hace superposición
Convierta middle_fragment en FrameLayout y cárguelo como se muestra a continuación y sus eventos se dispararán.
fuente
Puedes probar esto,
Paso 1: anula el método Tabselected en tu actividad
Paso 2: Usando el método estático haz lo que quieras en tu fragmento,
fuente
Yo uso en mi actividad - KOTLIN
fuente
Un fragmento siempre debe estar incrustado en una actividad y el ciclo de vida del fragmento se ve directamente afectado por el ciclo de vida de la actividad del host. Por ejemplo, cuando la actividad está en pausa, también lo están todos los fragmentos, y cuando la actividad se destruye, también lo están todos los fragmentos.
fuente
onPause()
El método funciona en la clase de actividad que puede usar:para el mismo propósito ..
fuente
Siga los pasos a continuación y obtendrá la respuesta necesaria.
1- Para ambos fragmentos, cree un nuevo padre abstracto.
2- Agregue un método abstracto personalizado que ambos deben implementar.
3- Llámalo desde la instancia actual antes de reemplazarla por la segunda.
fuente
Basado en la respuesta de @Gor , escribí algo similar en Kotlin. Coloque este código en
onCreate()
una actividad. Funciona para un fragmento visible. Si tieneViewPager
fragmentos, llamaráViewPager
al fragmento, no al anterior.Después de leer https://medium.com/@elye.project/puzzle-fragment-stack-pop-cause-issue-on-toolbar-8b947c5c07c6 , entendí que sería mejor en muchas situaciones adjuntar nuevos fragmentos
replace
, noadd
. Entonces una necesidad enonResume
algunos casos desaparecerá.fuente
Vocación
ft.replace
deben activar onPause (del fragmento reemplazado) y onResume (del fragmento reemplazado).Noto que su código se infla
login_fragment
en el fragmento de inicio y tampoco devuelve las vistas en onCreateView. Si se trata de errores tipográficos, ¿puede mostrar cómo se llaman estos fragmentos desde su actividad?fuente
Aunque con un código diferente, experimenté el mismo problema que el OP, porque originalmente usé
en vez de
Con "reemplazar", el primer fragmento se recrea cuando regresa del segundo fragmento y, por lo tanto, también se llama a onResume ().
fuente
Mientras crea una transacción fragmentada, asegúrese de agregar el siguiente código.
También asegúrese de confirmar la transacción después de agregarla al backstack
fuente