Fragment Lifecycle: fundamentos, métodos onCreateView e onViewCreated

Autor: IT Sectr Publicado: 2026-03-04 Tempo de leitura: 12 min

Fragment Lifecycle é uma sequência estritamente definida de métodos de callback que o Android invoca durante a vida de um Fragment: desde a criação (onAttach) até a remoção completa (onDetach). O Fragment tem um ciclo de vida mais complexo que a Activity — inclui 11 estados e 7 callbacks principais. O Fragment Lifecycle é gerenciado através do FragmentManager e está intimamente ligado ao ciclo de vida da Activity que o contém. De acordo com o Google, o Fragment é usado em 74% dos aplicativos Android que rodam na API Level 21+, tornando o entendimento do Fragment Lifecycle obrigatório para o desenvolvimento profissional Android. A documentação do Android sobre Fragment Lifecycle descreve todos os estados e garantias de chamada.

Principais pontos

  • Fragment Lifecycle inclui 11 callbacks: onAttach, onCreate, onCreateView, onViewCreated, onStart, onResume, onPause, onStop, onDestroyView, onDestroy, onDetach.
  • FragmentManager gerencia os estados do Fragment e garante a ordem correta das chamadas durante as transações.
  • onCreateView e onViewCreated são métodos-chave para criar e configurar a UI do Fragment.
  • Fragment pode sobreviver à sua Activity (ao girar a tela) e restaurar o estado através do onSaveInstanceState.
  • viewLifecycleOwner — um Lifecycle separado para a View do Fragment, destruído em onDestroyView.

Fragment Lifecycle: fundamentos do ciclo de vida

Fragment Lifecycle é um conjunto de estados e métodos interconectados pelos quais cada instância de Fragment passa desde a criação até a destruição. Ao contrário da Activity, o ciclo de vida do Fragment está ligado a dois contextos: o próprio Fragment (vive de onAttach a onDetach) e sua View (vive de onCreateView a onDestroyView). Essa separação é uma característica fundamental do Fragment, permitindo que ele sobreviva à destruição da View ao girar a tela sem destruir o próprio Fragment.

Sequência completa de callbacks do Fragment:

  • onAttach(Context) — Fragment se vincula à Activity. Chamado primeiro. Context é a Activity anfitriã.
  • onCreate(Bundle) — Fragment é inicializado. Aqui o ViewModel é criado, os adaptadores são configurados.
  • onCreateView(LayoutInflater, ViewGroup, Bundle) — a hierarquia de View do Fragment é criada. Retorna a View raiz.
  • onViewCreated(View, Bundle) — a View foi criada. Aqui os elementos de UI são configurados, as assinaturas LiveData são configuradas.
  • onStart() — Fragment se torna visível. Animações iniciam, sensores são registrados.
  • onResume() — Fragment está ativo, interagindo com o usuário.
  • onPause() — Fragment perde o foco. Animações são interrompidas.
  • onStop() — Fragment não está visível. Recursos não críticos são liberados.
  • onDestroyView() — a hierarquia de View é destruída. Referências à View são anuladas.
  • onDestroy() — Fragment é destruído. Corrotinas fora do viewModelScope são canceladas.
  • onDetach() — Fragment se desvincula da Activity. Limpeza final.

Segundo o Google, o fragmento médio em um aplicativo moderno passa pelo ciclo completo 3–5 vezes por sessão de usuário (devido a rotações de tela e navegação). O tratamento correto de todas as fases é a base da estabilidade da UI.

Estados do Fragment: de INITIALIZED a DESTROYED

FragmentManager gerencia o Fragment através de cinco estados principais, definidos na classe Fragment.State. Cada estado corresponde a um conjunto específico de callbacks que foram executados.

EstadoSignificadoCallbacks executados
INITIALIZEDFragment foi criado, mas a View ainda não está disponívelonAttach, onCreate
CREATEDView foi criada, mas Fragment não está visível+ onCreateView, onViewCreated
STARTEDFragment está visível, mas não ativo+ onStart
RESUMEDFragment está ativo, interagindo com o usuário+ onResume
DESTROYEDFragment foi destruído+ onDestroyView, onDestroy, onDetach

FragmentManager move o Fragment entre os estados com base nas ações do usuário e eventos do sistema. Ao adicionar um Fragment a um contêiner, ele passa sequencialmente por INITIALIZED → CREATED → STARTED → RESUMED. Ao remover — RESUMED → STARTED → CREATED → DESTROYED.

O estado CREATED é especial: a View pode ser destruída (após onDestroyView), mas o próprio Fragment permanece no estado CREATED (após onDestroyView, antes de onDestroy). Isso permite que o FragmentManager mantenha o Fragment na memória sem uma View, o que é necessário para sobreviver a rotações de tela.

Diferença entre Fragment Lifecycle e Activity Lifecycle

Fragment Lifecycle e Activity Lifecycle estão intimamente relacionados, mas têm diferenças fundamentais. Fragment sempre vive dentro de uma Activity, e seu ciclo de vida depende da Activity anfitriã, mas não é idêntico a ela.

AspectoActivityFragment
Número de callbacks7 (onCreate … onDestroy)11 (onAttach … onDetach)
Lifecycle separado para ViewNãoSim (viewLifecycleOwner)
Sobrevive à rotaçãoNão (é destruída)Sim (ViewModel + Fragment sobrevivem)
Dependência do anfitriãoNãoDepende do Activity Lifecycle
Salvamento de estadoonSaveInstanceStateonSaveInstanceState (nível de Fragment)
GerenciamentoSistemaFragmentManager

A principal diferença prática: ao girar a tela, a Activity é completamente destruída (onDestroy) e recriada (onCreate). O Fragment durante a rotação passa por onDestroyView (View destruída) → onCreateView (View recriada), mas o próprio Fragment e seu ViewModel permanecem vivos. Isso torna o Fragment um contêiner ideal para lógica de UI que precisa sobreviver a mudanças de configuração.

Ordem de chamadas durante a rotação da tela: Activity.onPause → Fragment.onPause → Activity.onStop → Fragment.onStop → Activity.onDestroy → Fragment.onDestroyView → (Activity destruída) → Activity.onCreate → Fragment.onAttach → Fragment.onCreate → Fragment.onCreateView → Fragment.onViewCreated → Activity.onStart → Fragment.onStart → Activity.onResume → Fragment.onResume.

FragmentManager: gerenciamento de estados e transações

FragmentManager é a classe central responsável por adicionar, remover, substituir fragments e gerenciar seus estados. O FragmentManager mantém a BackStack e garante a ordem correta dos callbacks durante as transações. Cada Activity e cada Fragment aninhado tem seu próprio FragmentManager.

Operações principais do FragmentManager:

  • beginTransaction() — abre uma transação para um grupo de operações.
  • add() — adiciona um Fragment a um contêiner. O Fragment passa pelo ciclo de vida completo até RESUMED.
  • replace() — substitui o Fragment atual por um novo. Equivale a remove() + add().
  • remove() — remove um Fragment. O Fragment passa pelo ciclo de vida de RESUMED a DESTROYED.
  • hide()/show() — oculta/mostra o Fragment sem destruir a View. O Fragment vai para STARTED ao ocultar, volta para RESUMED ao mostrar.
  • detach()/attach() — desanexa/reanexa o Fragment. detach destrói a View (onDestroyView), attach a recria (onCreateView).
  • addToBackStack() — adiciona a transação à BackStack para navegação para trás.

BackStack é a pilha de transações do FragmentManager. Ao pressionar o botão Voltar do sistema, a última transação na BackStack é revertida (popBackStack()). Um Fragment removido via popBackStack é restaurado. Se a BackStack estiver vazia, pressionar Voltar finaliza a Activity.

De acordo com o Google, 78% dos problemas com Fragment (duplicação, telas vazias, IllegalStateException) estão relacionados ao uso incorreto do FragmentManager. A regra principal: execute transações através de commit() (assíncrono) ou commitNow() (síncrono) dependendo do contexto. commit() garante a ordem correta sob múltiplas transações.

Salvando estado do Fragment: onSaveInstanceState

Fragment suporta seu próprio mecanismo de salvamento de estado através do onSaveInstanceState, que funciona independentemente da Activity. O Fragment salva o estado em um Bundle que é passado para onCreate e onCreateView durante a restauração.

Quando o Fragment salva o estado:

  • Ao girar a tela — a View é destruída, o Fragment salva o estado no Bundle.
  • Ao reconectar o Fragment à Activity após a morte do processo.
  • Ao chamar onSaveInstanceState da Activity (o sistema propaga o salvamento para todos os fragments filhos).

Abordagem moderna: use SavedStateHandle no ViewModel para salvar o estado do Fragment. O SavedStateHandle salva e restaura dados automaticamente ao girar a tela e na morte do processo, sem exigir onSaveInstanceState manual. O Google recomenda o SavedStateHandle como a forma preferida de salvar o estado da UI no Fragment.

setRetainInstance (obsoleto desde Fragment 1.3): anteriormente o Fragment podia ser retido via setRetainInstance(true) ao girar a tela. Esta abordagem foi substituída por ViewModel + SavedStateHandle, que funcionam de forma mais confiável e não requerem configuração especial.

viewLifecycleOwner: ciclo de vida separado da View

viewLifecycleOwner é um Lifecycle vinculado à View do Fragment (de onCreateView a onDestroyView). Este é um conceito fundamentalmente importante: assinaturas de LiveData/Flow feitas através do viewLifecycleOwner são automaticamente canceladas quando a View é destruída (onDestroyView), mas não afetam o próprio Fragment.

Diferença entre viewLifecycleOwner e o lifecycle do Fragment:

  • lifecycle (Fragment) — vive de onAttach a onDetach. As assinaturas permanecem ativas mesmo após a destruição da View.
  • viewLifecycleOwner — vive de onCreateView a onDestroyView. As assinaturas são canceladas ao destruir a View.

Por que isso é importante: se você assina o LiveData através do lifecycle do Fragment (this), após onDestroyView a assinatura permanece ativa e o LiveData tentará atualizar uma View nula, causando NPE. Assinar através do viewLifecycleOwner garante que após onDestroyView nenhuma atualização de UI ocorrerá.

Regra: no Fragment, sempre use viewLifecycleOwner para assinaturas de LiveData, Flow e corrotinas relacionadas à UI. Para corrotinas do ViewModel, use viewModelScope — ele está vinculado ao ViewModel, não ao Fragment.

Exemplos de código Fragment em Kotlin

Exemplo 1: Fragment básico com onViewCreated e viewLifecycleOwner

Demonstra a inicialização correta da UI e assinatura LiveData através do 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", "Atualizando lista: ${users.size} usuários")
        }
    }

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

O Fragment infla o layout em onCreateView, configura a UI e assina o LiveData em onViewCreated. A assinatura através do viewLifecycleOwner é um requisito obrigatório para evitar vazamentos de memória. onDestroyView registra a destruição da View — confirmação de que o Fragment sobrevive à rotação da tela.

Exemplo 2: Fragment com FragmentManager e transações

Demonstra a adição de Fragment via FragmentManager na Activity, substituição com BackStack e restauração.

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", "Carregando detalhes do usuário: $userId")
    }
}

A Activity usa supportFragmentManager para gerenciar fragments. A transação add() com BackStack garante que ao pressionar Voltar o HomeFragment seja restaurado. openDetail() substitui o Fragment atual por DetailFragment com argumentos. A verificação de savedInstanceState == null previne duplicação de fragments ao girar a tela.

Exemplo 3: Fragment com LifecycleObserver e StateFlow

Uso de Flow e StateFlow no Fragment com viewLifecycleOwner para atualizações reativas 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 da pesquisa: ${results.size}")
            }
        }
    }

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

O Fragment usa View Binding para acessar a View. A corrotina viewLifecycleOwner.lifecycleScope.launch é automaticamente cancelada quando a View é destruída. O binding é anulado em onDestroyView para prevenir vazamentos. O StateFlow garante a atualização dos dados ao recriar a View.

Perguntas frequentes

Como o onViewCreated difere do onCreateView?

onCreateView cria e retorna a View raiz do Fragment. onViewCreated é chamado imediatamente após a criação da View, garantindo que a View está completamente inicializada e pronta para configuração (findViewById, assinaturas). O Google recomenda apenas inflar o layout em onCreateView e fazer toda a configuração da UI em onViewCreated.

Quando o Fragment é realmente destruído — em onDestroy ou onDetach?

onDestroy — Fragment é destruído como objeto (ViewModel é limpo, corrotinas são canceladas). onDetach é o último callback, após o qual o Fragment se desvincula da Activity. Praticamente todos os recursos devem ser liberados em onDestroyView (View) e onDestroy (Fragment). onDetach é para limpar referências à Activity.

Por que o Fragment desaparece após girar a tela?

O Fragment desaparece se não foi adicionado ao FragmentManager através de uma transação com preservação na BackStack ou se a Activity não restaura o FragmentManager em onCreate. Solução: adicione o Fragment programaticamente através de supportFragmentManager.beginTransaction().add() em onCreate com a verificação de savedInstanceState == null.

Um Fragment pode existir sem uma Activity?

Não. Fragment está sempre vinculado a uma Activity através do FragmentManager. Mesmo ao girar a tela, a Activity é recriada e o Fragment é reanexado à nova Activity. Criar um Fragment fora de uma Activity é impossível — o construtor do Fragment requer um construtor vazio para restauração pelo sistema.

O que são fragments aninhados e para que servem?

Fragments aninhados (nested fragments) são Fragments dentro de outro Fragment. São usados para construir telas complexas: painéis de abas, painéis com guias, master-detail. Fragments aninhados são gerenciados pelo FragmentManager filho (childFragmentManager). O Google recomenda não exceder 2 níveis de aninhamento para evitar problemas de desempenho.

Resumo

  • Fragment Lifecycle inclui 11 callbacks: onAttach → onCreate → onCreateView → onViewCreated → onStart → onResume → onPause → onStop → onDestroyView → onDestroy → onDetach.
  • FragmentManager gerencia os estados do Fragment (INITIALIZED → CREATED → STARTED → RESUMED → DESTROYED) e a BackStack de transações.
  • Fragment sobrevive à rotação da tela — a View é destruída (onDestroyView), mas o Fragment e o ViewModel permanecem vivos.
  • viewLifecycleOwner é um Lifecycle separado para a View do Fragment; obrigatório para assinaturas LiveData e corrotinas de UI.
  • Salvamento de estado do Fragment — através de onSaveInstanceState ou SavedStateHandle no ViewModel.
  • As transações de Fragment são executadas através do FragmentManager com commit() (assíncrono) ou commitNow() (síncrono).
  • Sempre anule o binding e as referências à View em onDestroyView para prevenir vazamentos de memória.

Vamos desenvolver um aplicativo móvel chave na mão

A IT Sectr cria aplicativos para iOS e Android para startups e empresas desde 2017. Nós vamos aconselhá-lo e propor a melhor solução.

Discutir o projeto

Leia também