Fragment onResume () & onPause () no se llama en backstack
Tengo múltiples fragmentos dentro de una actividad. Al hacer clic en un botón, estoy comenzando un nuevo fragmento, agregándolo a backstack. Naturalmente esperaba que se llamara al método onPause()
del Fragmento actual y onResume()
del Fragmento nuevo. Bueno, no está sucediendo.
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, {[10]]}
- Cuando se hace clic en el botón, LoginFragment se reemplaza con
HomeFragment,
onPause()
de LoginFragment, yonResume()
de HomeFragment se llama - Cuando se presiona back, HomeFragment se abre y LoginFragment se
seen, and
onPause()
of HomeFragment andonResume()
of LoginFragment se llama.
Lo que estoy recibiendo es,
- Cuando se hace clic en el botón, HomeFragment está reemplazando correctamente LoginFragment , onResume () of HomeFragment se llama, pero onPause() de LoginFragment nunca se llama.
- Cuando se presiona hacia atrás, HomeFragment aparece correctamente para revelar LoginFragment , onPause () of HomeFragment se llama, pero onResume() de LoginFragment nunca se llama.
¿Es este el comportamiento normal? ¿Por qué onResume()
of LoginFragment no recibe una llamada cuando presiono el botón atrás?
15 answers
Los fragmentos onResume()
o onPause()
se llama sólo cuando las Actividades onResume()
o onPause()
es llamado.
Están estrechamente acoplados al Activity
.
Lea la sección Manejo del Ciclo de vida del fragmento de este artículo.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-05-22 10:06:17
- Puesto que ha utilizado
ft2.replace()
,FragmentTransaction.remove()
se llama al método y se eliminaráLoginfragment
. Refiérase a esto . Así queonStop()
deLoginFragment
se llamará en lugar deonPause()
. (Como el nuevo fragmento sustituye por completo el antiguo). - Pero puesto que también
utilizado
ft2.addtobackstack()
, el estado de laLoginfragment
será guardado como un paquete y al hacer clic en el botón atrás deHomeFragment
,onViewStateRestored()
será llamado seguido poronStart()
deLoginFragment
. Así que eventualmenteonResume()
no será llamado.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-04-27 14:10:38
Si realmente desea reemplazar el fragmento dentro de otro fragmento, debe usar Fragmentos anidados.
En su código debe reemplazar
final FragmentManager mFragmentmanager = getFragmentManager();
Con
final FragmentManager mFragmentmanager = getChildFragmentManager();
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-12-11 23:46:32
Aquí está mi versión más robusta de la respuesta de Gor (usando fragmentos.size () no es confiable debido a que el tamaño no se decrementa después de que el fragmento se revienta)
getFragmentManager().addOnBackStackChangedListener(new FragmentManager.OnBackStackChangedListener() {
@Override
public void onBackStackChanged() {
if (getFragmentManager() != null) {
Fragment topFrag = NavigationHelper.getCurrentTopFragment(getFragmentManager());
if (topFrag != null) {
if (topFrag instanceof YourFragment) {
//This fragment is being shown.
} else {
//Navigating away from this fragment.
}
}
}
}
});
Y el método 'getCurrentTopFragment':
public static Fragment getCurrentTopFragment(FragmentManager fm) {
int stackCount = fm.getBackStackEntryCount();
if (stackCount > 0) {
FragmentManager.BackStackEntry backEntry = fm.getBackStackEntryAt(stackCount-1);
return fm.findFragmentByTag(backEntry.getName());
} else {
List<Fragment> fragments = fm.getFragments();
if (fragments != null && fragments.size()>0) {
for (Fragment f: fragments) {
if (f != null && !f.isHidden()) {
return f;
}
}
}
}
return null;
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-11-24 17:41:30
Tengo un código muy similar al tuyo y si funciona onPause () y onResume (). Al cambiar el fragmento, estas funciones se activan respectivamente.
Código en fragmento:
@Override
public void onResume() {
super.onResume();
sensorManager.registerListener(this, proximidad, SensorManager.SENSOR_DELAY_NORMAL);
sensorManager.registerListener(this, brillo, SensorManager.SENSOR_DELAY_NORMAL);
Log.e("Frontales","resume");
}
@Override
public void onPause() {
super.onPause();
sensorManager.unregisterListener(this);
Log.e("Frontales","Pause");
}
Registro cuando el cambio de fragmento:
05-19 22:28:54.284 2371-2371/madi.cajaherramientas E/Frontales: resume
05-19 22:28:57.002 2371-2371/madi.cajaherramientas E/Frontales: Pause
05-19 22:28:58.697 2371-2371/madi.cajaherramientas E/Frontales: resume
05-19 22:29:00.840 2371-2371/madi.cajaherramientas E/Frontales: Pause
05-19 22:29:02.248 2371-2371/madi.cajaherramientas E/Frontales: resume
05-19 22:29:03.718 2371-2371/madi.cajaherramientas E/Frontales: Pause
Fragmento onCreateView:
View rootView;
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
rootView = inflater.inflate(R.layout.activity_proximidad, container, false);
ButterKnife.bind(this,rootView);
inflar();
setTextos();
return rootView;
}
Acción cuando pulso hacia atrás (en la actividad donde cargo el fragmento):
@Override
public void onBackPressed() {
int count = getFragmentManager().getBackStackEntryCount();
if (count == 0) {
super.onBackPressed();
} else {
getFragmentManager().popBackStack();
}
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-05-19 20:45:14
Simplemente no puede agregar un fragmento a un fragmento. Esto tiene que suceder en el FragmentActivity. Asumo que estás creando el LoginFragment en un FragmentActivity, por lo que para que esto funcione, necesitas agregar el HomeFragment a través de FragmentActivity cuando se cierre el inicio de sesión.
El punto general es que necesita una clase FragmentActivity desde la que agregue cada Fragmento al FragmentManager. No es posible hacer esto dentro de una clase de Fragmento.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-10-11 16:38:46
Si agrega el fragmento en XML, no puede intercambiarlo dinámicamente. Lo que sucede es que ellos son demasiado, por lo que los eventos no se disparan como uno esperaría. La cuestión está documentada en esta pregunta. FragmenManager reemplazar hace superposición
Convierte middle_fragment en un FrameLayout, y cárgalo como abajo y tus eventos se activarán.
getFragmentManager().beginTransation().
add(R.id.middle_fragment, new MiddleFragment()).commit();
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-05-23 12:26:26
getFragmentManager().addOnBackStackChangedListener(new FragmentManager.OnBackStackChangedListener() {
@Override
public void onBackStackChanged() {
List<Fragment> fragments = getFragmentManager().getFragments();
if (fragments.size() > 0 && fragments.get(fragments.size() - 1) instanceof YoureFragment){
//todo if fragment visible
} else {
//todo if fragment invisible
}
}
});
Pero ten cuidado si hay más de un fragmento visible
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-10-13 13:47:59
Lo que hago en fragmento hijo:
@Override
public void onDetach() {
super.onDetach();
ParentFragment pf = (ParentFragment) this.getParentFragment();
pf.onResume();
}
Y luego sobreescribir onResume en ParentFragment
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-12-10 09:01:58
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 host. Por ejemplo, cuando la actividad se detiene, también lo son todos los fragmentos en ella, y cuando la actividad se destruye, también lo son todos los fragmentos
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-07-16 11:29:20
Puedes probar esto,
Paso 1: Anula el método Tabselected en tu actividad
@Override
public void onTabSelected(ActionBar.Tab tab, FragmentTransaction fragmentTransaction) {
// When the given tab is selected, switch to the corresponding page in
// the ViewPager.
try {
if(MyEventsFragment!=null && tab.getPosition()==3)
{
MyEvents.fragmentChanged();
}
}
catch (Exception e)
{
}
mViewPager.setCurrentItem(tab.getPosition());
}
Paso 2: Usando el método estático haz lo que quieras en tu fragmento,
public static void fragmentChanged()
{
Toast.makeText(actvity, "Fragment Changed", Toast.LENGTH_SHORT).show();
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-01-20 12:25:31
onPause()
el método funciona en la clase de actividad que puede usar:
public void onDestroyView(){
super.onDestroyView
}
Para el mismo propósito..
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-04-02 19:29:51
Siga los pasos a continuación y obtendrá la respuesta necesaria
1 - Para ambos fragmentos, cree un nuevo padre abstracto.
2-Añadir un método abstracto personalizado que debe ser implementado por ambos.
3-Llámelo desde la instancia actual antes de reemplazarlo con la segunda.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-04-09 21:09:33
Basado en la respuesta de @Gor Escribí algo similar en Kotlin. Coloque este código en onCreate()
de una actividad. Funciona para un fragmento visible. Si tienes ViewPager
con fragmentos, llamará al fragmento de ViewPager
, no a uno anterior.
supportFragmentManager.addOnBackStackChangedListener {
supportFragmentManager.fragments.lastOrNull()?.onResume()
}
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 con replace
, no add
. Así que una necesidad en onResume
en algunos casos desaparecerán.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-08-02 12:39:38
Al crear una transacción de fragmento, asegúrese de agregar el siguiente código.
// Replace whatever is in the fragment_container view with this fragment,
// and add the transaction to the back stack
transaction.replace(R.id.fragment_container, newFragment);
transaction.addToBackStack(null);
También asegúrese de confirmar la transacción después de agregarla a backstack
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-03-07 13:26:44