android - una - Fragmento onResume() y onPause() no se llama en backstack
onresume fragment android (14)
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
Tengo múltiples fragmentos dentro de una actividad. En un botón, haga clic en Comenzaré un nuevo fragmento y lo agregaré al backstack. Naturalmente, esperaba que se onPause()
método onPause()
del Fragmento actual y onResume()
del nuevo Fragmento. 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, fue,
- Cuando se hace clic en el botón, LoginFragment se reemplaza con HomeFragment ,
onPause()
de LoginFragment yonResume()
de HomeFragment se llama - Cuando se presiona atrás, HomeFragment aparece y se ve LoginFragment , y se
onPause()
de HomeFragment yonResume()
de LoginFragment .
Lo que obtengo es,
- Cuando se hace clic en el botón, HomeFragment reemplaza correctamente a LoginFragment , onResume () de HomeFragment se llama, pero onPause () de LoginFragment nunca se llama.
- Cuando se presiona de nuevo, 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é onResume()
de LoginFragment no se llama cuando presiono el botón Atrás?
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 disminuye después de que se hace saltar el fragmento)
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;
}
Lo que hago en fragmento de niño:
@Override
public void onDetach() {
super.onDetach();
ParentFragment pf = (ParentFragment) this.getParentFragment();
pf.onResume();
}
Y luego anular onResume en ParentFragment
Los fragmentos onResume()
o onPause()
se onPause()
solo cuando se onResume()
las actividades onResume()
o onPause()
. Están estrechamente relacionados con la Activity
.
Lea la sección Manejando el Fragmento del Ciclo de Vida de este artículo .
Puedes probar esto,
Paso 1: anule el método Tabselected en su 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();
}
Si agrega el fragmento en XML, no puede intercambiarlos dinámicamente. Lo que ocurre es que son demasiado, por lo que los eventos no se disparan como uno esperaría. El problema está documentado en esta pregunta. FragmenManager replace hace overlay
Convierta middle_fragment en FrameLayout y cárguelo de la siguiente manera y sus eventos se activarán.
getFragmentManager().beginTransation().
add(R.id.middle_fragment, new MiddleFragment()).commit();
Si realmente quieres reemplazar el fragmento dentro de otro fragmento, debes usar Fragmentos anidados .
En tu código debes reemplazar
final FragmentManager mFragmentmanager = getFragmentManager();
con
final FragmentManager mFragmentmanager = getChildFragmentManager();
Siempre se debe incrustar un fragmento 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 son todos los fragmentos, y cuando se destruye la actividad, también lo hacen todos los fragmentos
Tengo un código muy similar al suyo 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 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();
}
}
Usted simple no puede agregar un fragmento a un fragmento. Esto debe suceder en FragmentActivity. Supongo que está creando LoginFragment en una FragmentActivity, por lo que para que esto funcione debe agregar el 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.
onPause()
método onPause()
funciona en clase de actividad que puede usar:
public void onDestroyView(){
super.onDestroyView
}
para el mismo propósito ...
Siga los pasos a continuación y obtendrá la respuesta necesaria
1- Para ambos fragmentos, cree un nuevo padre primario abstracto.
2- Agregue un método abstracto personalizado que ambos deberían implementar.
3- Llamar desde la instancia actual antes de reemplazar con la segunda.
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
- Como ha utilizado
ft2.replace()
, se llama al métodoFragmentTransaction.remove()
y seLoginfragment
elLoginfragment
. Consulte this . Entonces seonStop()
deLoginFragment
lugar deonPause()
. (Como el nuevo fragmento reemplaza completamente al anterior). - Pero como también ha utilizado
ft2.addtobackstack()
, el estado delLoginfragment
deLoginfragment
deLoginfragment
se guardará como un paquete y cuando haga clic en el botónHomeFragment
deHomeFragment
, seonViewStateRestored()
seguido deonStart()
deLoginFragment
. Por lo tanto, eventualmenteonResume()
no se llamará.