Fragment Lifecycle: conceptos básicos, métodos onCreateView y onViewCreated

Autor: IT Sectr Publicado: 2026-03-04 Tiempo de lectura: 12 min

Fragment Lifecycle es una secuencia estrictamente definida de métodos callback que Android invoca durante la vida de un Fragment: desde la creación (onAttach) hasta la eliminación completa (onDetach). Fragment tiene un ciclo de vida más complejo que Activity — incluye 11 estados y 7 callbacks principales. Fragment Lifecycle se gestiona a través de FragmentManager y está estrechamente vinculado al ciclo de vida de la Activity que lo contiene. Según Google, Fragment se utiliza en el 74% de las aplicaciones Android que funcionan en API Level 21+, lo que hace que comprender Fragment Lifecycle sea obligatorio para el desarrollo profesional de Android. La documentación de Android sobre Fragment Lifecycle describe todos los estados y garantías de llamada.

Aspectos clave

  • Fragment Lifecycle incluye 11 callbacks: onAttach, onCreate, onCreateView, onViewCreated, onStart, onResume, onPause, onStop, onDestroyView, onDestroy, onDetach.
  • FragmentManager gestiona los estados de Fragment y garantiza el orden correcto de las llamadas durante las transacciones.
  • onCreateView y onViewCreated son métodos clave para crear y configurar la UI de Fragment.
  • Fragment puede sobrevivir a su Activity (al rotar la pantalla) y restaurar el estado mediante onSaveInstanceState.
  • viewLifecycleOwner — un Lifecycle separado para la View de Fragment, destruido en onDestroyView.

Fragment Lifecycle: conceptos básicos del ciclo de vida

Fragment Lifecycle es un conjunto de estados y métodos interconectados por los que pasa cada instancia de Fragment desde su creación hasta su destrucción. A diferencia de Activity, el ciclo de vida de Fragment está vinculado a dos contextos: el propio Fragment (vive de onAttach a onDetach) y su View (vive de onCreateView a onDestroyView). Esta separación es una característica clave de Fragment, que permite sobrevivir a la destrucción de la View al rotar la pantalla sin destruir el propio Fragment.

Secuencia completa de callbacks de Fragment:

  • onAttach(Context) — Fragment se vincula a la Activity. Se llama primero. Context es la Activity anfitriona.
  • onCreate(Bundle) — Fragment se inicializa. Aquí se crea ViewModel, se configuran los adaptadores.
  • onCreateView(LayoutInflater, ViewGroup, Bundle) — se crea la jerarquía de View de Fragment. Devuelve la View raíz.
  • onViewCreated(View, Bundle) — la View ha sido creada. Aquí se configuran los elementos de UI, las suscripciones a LiveData.
  • onStart() — Fragment se vuelve visible. Se inician animaciones, se registran sensores.
  • onResume() — Fragment está activo, interactúa con el usuario.
  • onPause() — Fragment pierde el foco. Se detienen animaciones.
  • onStop() — Fragment no es visible. Se liberan recursos no críticos.
  • onDestroyView() — la jerarquía de View se destruye. Las referencias a View se anulan.
  • onDestroy() — Fragment se destruye. Las corrutinas que no están en viewModelScope se cancelan.
  • onDetach() — Fragment se desvincula de la Activity. Limpieza final.

Según Google, el fragmento promedio en una aplicación moderna pasa por el ciclo completo de 3 a 5 veces por sesión de usuario (debido a rotaciones de pantalla y navegación). El manejo correcto de todas las fases es la base de la estabilidad de la UI.

Estados de Fragment: de INITIALIZED a DESTROYED

FragmentManager gestiona Fragment a través de cinco estados principales, definidos en la clase Fragment.State. Cada estado corresponde a un conjunto específico de callbacks que se han ejecutado.

EstadoSignificadoCallbacks ejecutados
INITIALIZEDFragment está creado, pero la View aún no está disponibleonAttach, onCreate
CREATEDLa View está creada, pero Fragment no es visible+ onCreateView, onViewCreated
STARTEDFragment es visible, pero no activo+ onStart
RESUMEDFragment está activo, interactúa con el usuario+ onResume
DESTROYEDFragment está destruido+ onDestroyView, onDestroy, onDetach

FragmentManager mueve Fragment entre estados según las acciones del usuario y los eventos del sistema. Al agregar Fragment a un contenedor, pasa secuencialmente por INITIALIZED → CREATED → STARTED → RESUMED. Al eliminarlo — RESUMED → STARTED → CREATED → DESTROYED.

El estado CREATED es especial: la View puede destruirse (después de onDestroyView), pero el propio Fragment permanece en el estado CREATED (después de onDestroyView, antes de onDestroy). Esto permite que FragmentManager mantenga el Fragment en memoria sin View, lo que es necesario para sobrevivir a las rotaciones de pantalla.

Diferencia entre Fragment Lifecycle y Activity Lifecycle

Fragment Lifecycle y Activity Lifecycle están estrechamente relacionados pero tienen diferencias fundamentales. Fragment siempre vive dentro de una Activity, y su ciclo de vida depende de la Activity anfitriona, pero no es idéntico a ella.

AspectoActivityFragment
Cantidad de callbacks7 (onCreate … onDestroy)11 (onAttach … onDetach)
Lifecycle separado para ViewNoSí (viewLifecycleOwner)
Sobrevive a rotaciónNo (se destruye)Sí (ViewModel + Fragment sobreviven)
Dependencia del anfitriónNoDepende del Activity Lifecycle
Guardado de estadoonSaveInstanceStateonSaveInstanceState (a nivel de Fragment)
GestiónSistemaFragmentManager

La principal diferencia práctica: al rotar la pantalla, Activity se destruye completamente (onDestroy) y se crea de nuevo (onCreate). Fragment durante la rotación pasa por onDestroyView (la View se destruye) → onCreateView (la View se crea de nuevo), pero el propio Fragment y su ViewModel permanecen vivos. Esto hace que Fragment sea un contenedor ideal para la lógica de UI que debe sobrevivir a los cambios de configuración.

Orden de llamadas durante la rotación de pantalla: Activity.onPause → Fragment.onPause → Activity.onStop → Fragment.onStop → Activity.onDestroy → Fragment.onDestroyView → (Activity destruida) → Activity.onCreate → Fragment.onAttach → Fragment.onCreate → Fragment.onCreateView → Fragment.onViewCreated → Activity.onStart → Fragment.onStart → Activity.onResume → Fragment.onResume.

FragmentManager: gestión de estados y transacciones

FragmentManager es la clase central responsable de agregar, eliminar, reemplazar fragments y gestionar sus estados. FragmentManager mantiene la BackStack y garantiza el orden correcto de callbacks durante las transacciones. Cada Activity y cada Fragment anidado tienen su propio FragmentManager.

Operaciones principales de FragmentManager:

  • beginTransaction() — abre una transacción para un grupo de operaciones.
  • add() — agrega un Fragment a un contenedor. Fragment pasa por el ciclo de vida completo hasta RESUMED.
  • replace() — reemplaza el Fragment actual por uno nuevo. Equivale a remove() + add().
  • remove() — elimina un Fragment. Fragment pasa por el ciclo de vida de RESUMED a DESTROYED.
  • hide()/show() — oculta/muestra Fragment sin destruir la View. Fragment pasa a STARTED al ocultar, y vuelve a RESUMED al mostrar.
  • detach()/attach() — desvincula/vuelve a vincular Fragment. detach destruye la View (onDestroyView), attach la recrea (onCreateView).
  • addToBackStack() — agrega la transacción a BackStack para la navegación hacia atrás.

BackStack es la pila de transacciones de FragmentManager. Al presionar el botón de retroceso del sistema, la última transacción en BackStack se revierte (popBackStack()). Un Fragment eliminado mediante popBackStack se restaura. Si BackStack está vacío, presionar Atrás finaliza la Activity.

Según Google, el 78% de los problemas con Fragment (duplicación, pantallas vacías, IllegalStateException) están relacionados con el uso incorrecto de FragmentManager. La regla principal: ejecute las transacciones mediante commit() (de forma asíncrona) o commitNow() (de forma síncrona) según el contexto. commit() garantiza el orden correcto en múltiples transacciones.

Guardado del estado de Fragment: onSaveInstanceState

Fragment admite su propio mecanismo de guardado de estado a través de onSaveInstanceState, que funciona independientemente de Activity. Fragment guarda el estado en un Bundle que se pasa a onCreate y onCreateView durante la restauración.

Cuándo Fragment guarda el estado:

  • Al rotar la pantalla — la View se destruye, Fragment guarda el estado en Bundle.
  • Cuando Fragment se vuelve a vincular a Activity después de la muerte del proceso.
  • Cuando se llama a onSaveInstanceState desde Activity (el sistema propaga el guardado a todos los fragments secundarios).

Enfoque moderno: use SavedStateHandle en ViewModel para guardar el estado de Fragment. SavedStateHandle guarda y restaura datos automáticamente al rotar la pantalla y en caso de muerte del proceso, sin necesidad de onSaveInstanceState manual. Google recomienda SavedStateHandle como la forma preferida de guardar el estado de UI en Fragment.

setRetainInstance (obsoleto desde Fragment 1.3): anteriormente Fragment podía conservarse mediante setRetainInstance(true) al rotar la pantalla. Este enfoque ha sido reemplazado por ViewModel + SavedStateHandle, que funcionan de manera más confiable y no requieren configuración especial.

viewLifecycleOwner: ciclo de vida separado de la View

viewLifecycleOwner es un Lifecycle vinculado a la View de Fragment (de onCreateView a onDestroyView). Este es un concepto fundamentalmente importante: las suscripciones a LiveData/Flow realizadas a través de viewLifecycleOwner se cancelan automáticamente cuando la View se destruye (onDestroyView), pero no afectan al propio Fragment.

Diferencia entre viewLifecycleOwner y el lifecycle de Fragment:

  • lifecycle (Fragment) — vive de onAttach a onDetach. Las suscripciones permanecen activas incluso después de la destrucción de la View.
  • viewLifecycleOwner — vive de onCreateView a onDestroyView. Las suscripciones se cancelan al destruirse la View.

Por qué es importante: si se suscribe a LiveData a través del lifecycle de Fragment (this), después de onDestroyView la suscripción permanece activa y LiveData intentará actualizar una View nula, causando NPE. Suscribirse a través de viewLifecycleOwner garantiza que después de onDestroyView no se produzcan actualizaciones de UI.

Regla: en Fragment, use siempre viewLifecycleOwner para suscripciones a LiveData, Flow y corrutinas relacionadas con la UI. Para las corrutinas de ViewModel, use viewModelScope — está vinculado a ViewModel, no a Fragment.

Ejemplos de código Fragment en Kotlin

Ejemplo 1: Fragment básico con onViewCreated y viewLifecycleOwner

Demuestra la inicialización correcta de UI y la suscripción a LiveData a través de viewLifecycleOwner.

kotlin
class UserListFragment : Fragment() {
    private val viewModel: UserListViewModel by viewModels()

    override fun onCreateView(
        inflater: LayoutInflater,
        container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View {
        return inflater.inflate(R.layout.fragment_user_list, container, false)
    }

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
        val button: Button = view.findViewById(R.id.load_button)
        button.setOnClickListener { viewModel.loadUsers() }
        viewModel.users.observe(viewLifecycleOwner) { users ->
            Log.d("UserListFragment", "Actualizando lista: ${users.size} usuarios")
        }
    }

    override fun onDestroyView() {
        super.onDestroyView()
        Log.d("UserListFragment", "onDestroyView: View destruida")
    }
}

Fragment infla el layout en onCreateView, configura la UI y se suscribe a LiveData en onViewCreated. La suscripción a través de viewLifecycleOwner es un requisito obligatorio para prevenir fugas de memoria. onDestroyView registra la destrucción de la View — confirmación de que Fragment sobrevive a la rotación de pantalla.

Ejemplo 2: Fragment con FragmentManager y transacciones

Demuestra cómo agregar Fragment a través de FragmentManager en Activity, reemplazo con BackStack y restauración.

kotlin
class HostActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_host)
        if (savedInstanceState == null) {
            supportFragmentManager.beginTransaction()
                .add(R.id.fragment_container, HomeFragment())
                .addToBackStack(null)
                .commit()
        }
    }

    fun openDetail(userId: String) {
        supportFragmentManager.beginTransaction()
            .replace(R.id.fragment_container, DetailFragment.newInstance(userId))
            .addToBackStack(null)
            .commit()
    }

    override fun onBackPressed() {
        if (supportFragmentManager.backStackEntryCount > 0) {
            supportFragmentManager.popBackStack()
        } else {
            super.onBackPressed()
        }
    }
}

class DetailFragment : Fragment() {
    companion object {
        fun newInstance(userId: String): DetailFragment {
            return DetailFragment().apply {
                arguments = Bundle().apply { putString("user_id", userId) }
            }
        }
    }

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
        val userId = arguments?.getString("user_id")
        Log.d("DetailFragment", "Cargando detalles del usuario: $userId")
    }
}

Activity usa supportFragmentManager para gestionar fragments. La transacción add() con BackStack garantiza que al presionar Atrás se restaure HomeFragment. openDetail() reemplaza el Fragment actual por DetailFragment con argumentos. La comprobación de savedInstanceState == null previene la duplicación de fragments al rotar la pantalla.

Ejemplo 3: Fragment con LifecycleObserver y StateFlow

Uso de Flow y StateFlow en Fragment con viewLifecycleOwner para actualizaciones reactivas de UI.

kotlin
class SearchFragment : Fragment() {
    private val viewModel: SearchViewModel by viewModels()
    private var binding: FragmentSearchBinding? = null

    override fun onCreateView(
        inflater: LayoutInflater,
        container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View {
        binding = FragmentSearchBinding.inflate(inflater, container, false)
        return binding!!.root
    }

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
        binding?.searchButton?.setOnClickListener {
            viewModel.search(binding?.queryInput?.text.toString())
        }
        viewLifecycleOwner.lifecycleScope.launch {
            viewModel.searchResults.collectLatest { results ->
                Log.d("SearchFragment", "Resultados de búsqueda: ${results.size}")
            }
        }
    }

    override fun onDestroyView() {
        super.onDestroyView()
        binding = null
    }
}

Fragment usa View Binding para acceder a la View. La corrutina viewLifecycleOwner.lifecycleScope.launch se cancela automáticamente cuando la View se destruye. El binding se anula en onDestroyView para prevenir fugas de memoria. StateFlow garantiza la actualización de los datos al recrearse la View.

Preguntas frecuentes

¿En qué se diferencia onViewCreated de onCreateView?

onCreateView crea y devuelve la View raíz de Fragment. onViewCreated se llama inmediatamente después de la creación de la View, garantizando que la View está completamente inicializada y lista para la configuración (findViewById, suscripciones). Google recomienda solo inflar el layout en onCreateView y hacer toda la configuración de UI en onViewCreated.

¿Cuándo se destruye realmente Fragment — en onDestroy o en onDetach?

onDestroy — Fragment se destruye como objeto (ViewModel se limpia, las corrutinas se cancelan). onDetach es el último callback, después del cual Fragment se desvincula de la Activity. Prácticamente todos los recursos deben liberarse en onDestroyView (View) y onDestroy (Fragment). onDetach es para limpiar referencias a la Activity.

¿Por qué Fragment desaparece después de rotar la pantalla?

Fragment desaparece si no fue agregado a FragmentManager mediante una transacción con preservación en BackStack o si Activity no restaura FragmentManager en onCreate. Solución: agregue Fragment programáticamente a través de supportFragmentManager.beginTransaction().add() en onCreate con la comprobación de savedInstanceState == null.

¿Puede existir un Fragment sin una Activity?

No. Fragment siempre está vinculado a una Activity a través de FragmentManager. Incluso al rotar la pantalla, Activity se recrea y Fragment se vuelve a vincular a la nueva Activity. No es posible crear un Fragment fuera de una Activity — el constructor de Fragment requiere un constructor vacío para la restauración por parte del sistema.

¿Qué son los fragments anidados y para qué se necesitan?

Los fragments anidados (nested fragments) son Fragments dentro de otro Fragment. Se utilizan para construir pantallas complejas: paneles de pestañas, paneles con fichas, master-detail. Los fragments anidados se gestionan mediante el FragmentManager secundario (childFragmentManager). Google recomienda no superar los 2 niveles de anidamiento para evitar problemas de rendimiento.

Resumen

  • Fragment Lifecycle incluye 11 callbacks: onAttach → onCreate → onCreateView → onViewCreated → onStart → onResume → onPause → onStop → onDestroyView → onDestroy → onDetach.
  • FragmentManager gestiona los estados de Fragment (INITIALIZED → CREATED → STARTED → RESUMED → DESTROYED) y la BackStack de transacciones.
  • Fragment sobrevive a la rotación de pantalla — la View se destruye (onDestroyView), pero Fragment y ViewModel permanecen vivos.
  • viewLifecycleOwner es un Lifecycle separado para la View de Fragment; obligatorio para suscripciones a LiveData y corrutinas de UI.
  • Guardado del estado de Fragment — mediante onSaveInstanceState o SavedStateHandle en ViewModel.
  • Las transacciones de Fragment se ejecutan a través de FragmentManager con commit() (asíncrono) o commitNow() (síncrono).
  • Siempre anule el binding y las referencias a la View en onDestroyView para prevenir fugas de memoria.

Desarrollaremos una aplicación móvil llave en mano

IT Sectr crea aplicaciones para iOS y Android para startups y empresas desde 2017. Le asesoraremos y le propondremos la mejor solución.

Discutir el proyecto

Lea también