Ciclo de vida del fragmento: ¿a qué método se llama mostrar/ocultar?

5 minutos de lectura

avatar de usuario
Felipe Jahoda

Estoy usando el siguiente método para cambiar entre Fragmentos (en mi NavigationDrawer) mostrándolos/ocultándolos.

protected void showFragment(int container, Fragment fragment, String tag, String lastTag, boolean addToBackStack ) {

        FragmentManager fragmentManager = getSupportFragmentManager();
        FragmentTransaction transaction = fragmentManager.beginTransaction();

        if ( lastTag != null && !lastTag.equals("")) {
            Fragment lastFragment = fragmentManager.findFragmentByTag( lastTag );
            if ( lastFragment != null ) {
                transaction.hide( lastFragment );
            }
        }

        if ( fragment.isAdded() ) {
            transaction.show( fragment );
        }
        else {
            transaction.add( container, fragment, tag );
        }

        if ( addToBackStack ) {
            transaction.addToBackStack( tag );
        }

        transaction.commit();

        // set the active tag
        activeFragTag = tag;
    }

Lo que no tengo claro es qué método del ciclo de vida de Fragmentos se llama cuando lo muestro o lo oculto. (Dado que no hay un método como onShow() o onHide(), no estoy muy seguro de qué usar). Quiero realizar acciones específicas al mostrar y ocultar un determinado Fragmento.

  • cuando usted llama Fragmento.show() luego, en algún momento más tarde, el fragmento desencadena onCreate()seguido por onCreateDialog()seguido por onCreateView()

    – Alguien en algún lugar

    31 de octubre de 2017 a las 17:09


avatar de usuario
sergej shafarenka

Similar al ciclo de vida de la actividad, las llamadas de Android enInicio() cuando el fragmento se vuelve visible. onStop() normalmente se llama cuando el fragmento se vuelve invisible, pero también se puede llamar más adelante en el tiempo.

Dependiendo de su diseño, Android puede llamar onStart() incluso, cuando su Fragmento aún no es visible, pero pertenece a un contenedor padre visible. Por ejemplo, esto es válido para android.support.v4.view.ViewPager que requiere que usted anule Fragment.setUserVisibleHint() método. En cualquier caso, si necesita registrar o cancelar el registro de BroadcastReceivers u otros oyentes, puede usar de forma segura onStart() y onStop() métodos porque esos serán llamados siempre.

Nota: Algunos contenedores de fragmentos pueden mantener iniciados fragmentos invisibles. Para manejar esta situación, puede anular Fragment.onHiddenChanged(boolean hidden). De acuerdo con la documentaciónun fragmento debe ser ambos iniciado y visible (no oculto)para que sea visible para el usuario.

Actualizar: Si utiliza android.support.v4.widget.DrawerLayout luego, un fragmento debajo del cajón permanece abierto y visible incluso cuando el cajón está abierto. En este caso necesitas usar DrawerLayout.setDrawerListener() y escucha por onDrawerClosed() y onDrawerOpened() devoluciones de llamada

  • onStop y onPause no se llaman cuando un fragmento se vuelve invisible usando una transacción. Sin embargo onHiddenChanged se llama como sugiere s1rius respuesta

    – Yoann Hercouet

    26 de abril de 2014 a las 8:53

  • Esto no funciona en NavigationDrawer. onHiddenChanged no se llama en la biblioteca de soporte v4/v11. onStart y onResume también se llamarán no siempre, cuando se abra el diseño del cajón.

    – drdrej

    14 mayo 2014 a las 13:23

  • @drdrej El problema es que el cajón no oculta completamente el fragmento debajo. Si usa DrawerLayout de la biblioteca de soporte, necesita usar DrawerListener.

    – sergej shafarenka

    14 mayo 2014 a las 18:19

  • Como se dijo, esta respuesta es simplemente incorrecta.

    – Mitch

    23 de febrero de 2021 a las 6:31

@Sobrescribo este método y resuelvo mi problema:

@Override
public void onHiddenChanged(boolean hidden) {
    super.onHiddenChanged(hidden);
    if (hidden) {
        //do when hidden
    } else {
       //do when show
    }
}

  • Intenté no resolver pero usando setUserVisibleHint como se muestra en stackoverflow.com/a/18375436/1815624 funciona

    – Crandell WS

    04/04/2016 a las 16:37

  • Quiero enmarcar este comentario 🙂 Eres perfecto

    – Vahit Keskin

    8 abr a las 7:14

avatar de usuario
biraj zalavadia

por supuesto, puede @Override el siguiente método para hacerlo:

@Override
    public void setUserVisibleHint(boolean isVisibleToUser) {
        super.setUserVisibleHint(isVisibleToUser);
        if (isVisibleToUser) {
            // Do your Work
        } else {
            // Do your Work
        }
    }

  • Y uno puede saber fácilmente si el fragmento es visible para el usuario o no llamando getUserVisibleHint()

    – ARIF

    1 de septiembre de 2016 a las 14:36

  • setUserVisibleHint funciona con el localizador de vistas, pero no con el contenedor de fragmentos normal.

    – MikeL

    18 de febrero de 2017 a las 22:03

  • Gracias esto resuelve mi problema 🙂

    – RAJESH KUMAR ARUMUGAM

    13 de octubre de 2017 a las 6:49

  • Esto funcionó para mí en ViewPager. onHiddenChanged no funcionó.

    – vive el amor

    10 de noviembre de 2018 a las 17:41


  • ¡Resolvió mi problema!

    – Jad Chahiné

    10 abr 2019 a las 20:25

Puede usar ‘onCreateView’ (o ‘onActivityCreated’) y ‘onHiddenChanged’. Use ‘onCreateView’ para el primer programa y use ‘onHiddenChanged’ para más tarde. ‘setMenuVisibility’ no se llama en el control de transacciones.

@Override
public View OnCreateView() {
   // fragment will show first
}

@Override
public void onHiddenChanged(boolean hidden) {
    if (!hidden) {
        // fragment will show 
    }
    else {
        // fragment will hide
    }
}

avatar de usuario
alan yuan

El comportamiento del buscapersonas de vista de fragmentos es diferente del contenedor de fragmentos normal.

Prueba este código:

    boolean mIsVisibleToUser;

    /**
     * is visible to user
     */
    public void show() {
        //do when show
    }

    /**
     * is invisible to user
     */
    public void hide() {
        //do when gone
    }

    @Override
    public void onResume() {
        super.onResume();
        if (!mIsVisibleToUser && getUserVisibleHint()) {
            mIsVisibleToUser = true;
            show();
        }
    }

    @Override
    public void onPause() {
        super.onPause();
        if (mIsVisibleToUser && getUserVisibleHint()) {
            mIsVisibleToUser = false;
            hide();
        }
    }

    @Override
    public void setUserVisibleHint(boolean isVisibleToUser) {
        super.setUserVisibleHint(isVisibleToUser);
        if (isResumed()) {
            if (mIsVisibleToUser != isVisibleToUser) {
                mIsVisibleToUser = isVisibleToUser;
                if (isVisibleToUser) show();
                else hide();
            }
        }
    }

    public boolean isVisibleToUser() {
        return mIsVisibleToUser;
    }

avatar de usuario
Ahmad Aghazadeh

Prueba este código:

@Override
public void setUserVisibleHint(boolean visible)
{
    super.setUserVisibleHint(visible);
    if (visible && isResumed())
    {
         onResume();
    }
}

@Override
public void onResume()
{
    super.onResume();
    if (!getUserVisibleHint())
    {
        return;
    }

    //Add your code this section
}

avatar de usuario
Junco

Simplemente intente esto en su setUserVisibleHint()

@Override
public void setUserVisibleHint(boolean isVisibleToUser) {
    super.setUserVisibleHint(isVisibleToUser);
    if(isVisibleToUser && getView() != null){
        isActive = true;
        init();
    }else if(isVisibleToUser && getView() == null){
        isActive = false;
    }else{
        isActive = true;
    }
}

Y crea este código en onCreateView() :

public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
  if(!isActive){
      init();
  }
}

  • isVisibleToUser && getView() != null funcionó perfecto para mí!

    – anni

    6 de enero de 2018 a las 22:29

¿Ha sido útil esta solución?