Fragment Lifecycle: Basics, onCreateView and onViewCreated Methods

Author: IT Sectr Published: 2026-03-04 Reading time: 12 min

Fragment Lifecycle is a strictly defined sequence of callback methods that Android invokes throughout the life of a Fragment: from creation (onAttach) to complete removal (onDetach). Fragment has a more complex lifecycle than Activity — it includes 11 states and 7 main callbacks. Fragment Lifecycle is managed through FragmentManager and is closely tied to the lifecycle of its host Activity. According to Google, Fragment is used in 74% of Android applications running on API Level 21+, making knowledge of Fragment Lifecycle essential for professional Android development. Android Documentation on Fragment Lifecycle describes all states and call guarantees.

Key Takeaways

  • Fragment Lifecycle includes 11 callbacks: onAttach, onCreate, onCreateView, onViewCreated, onStart, onResume, onPause, onStop, onDestroyView, onDestroy, onDetach.
  • FragmentManager manages Fragment states and ensures correct callback ordering during transactions.
  • onCreateView and onViewCreated are key methods for creating and configuring Fragment UI.
  • Fragment can outlive its Activity (on screen rotation) and restore state via onSaveInstanceState.
  • viewLifecycleOwner — a separate Lifecycle for Fragment View, destroyed in onDestroyView.

Fragment Lifecycle: Lifecycle Basics

Fragment Lifecycle is a set of interconnected states and methods that every Fragment instance goes through from creation to destruction. Unlike Activity, the Fragment lifecycle is tied to two contexts: the Fragment itself (lives from onAttach to onDetach) and its View (lives from onCreateView to onDestroyView). This separation is a key feature of Fragment, allowing it to survive View destruction on screen rotation without destroying the Fragment itself.

Complete sequence of Fragment callbacks:

  • onAttach(Context) — Fragment attaches to the Activity. Called first. Context is the host Activity.
  • onCreate(Bundle) — Fragment is initialized. Here ViewModel is created, adapters are configured.
  • onCreateView(LayoutInflater, ViewGroup, Bundle) — Fragment View hierarchy is created. Returns the root View.
  • onViewCreated(View, Bundle) — View has been created. Here UI elements are configured, LiveData subscriptions are set up.
  • onStart() — Fragment becomes visible. Animations start, sensors are registered.
  • onResume() — Fragment is active, interacting with the user.
  • onPause() — Fragment loses focus. Animations are stopped.
  • onStop() — Fragment is not visible. Non-critical resources are released.
  • onDestroyView() — View hierarchy is destroyed. View references are nullified.
  • onDestroy() — Fragment is destroyed. Coroutines not in viewModelScope are canceled.
  • onDetach() — Fragment detaches from the Activity. Final cleanup.

According to Google, the average fragment in a modern application goes through the full cycle 3–5 times per user session (due to screen rotations and navigation). Correct handling of all phases is the foundation of UI stability.

Fragment States: From INITIALIZED to DESTROYED

FragmentManager manages Fragment through five main states, defined in the Fragment.State class. Each state corresponds to a specific set of callbacks that have been executed.

StateMeaningCompleted Callbacks
INITIALIZEDFragment is created, but View is not yet availableonAttach, onCreate
CREATEDView is created, but Fragment is not visible+ onCreateView, onViewCreated
STARTEDFragment is visible, but not active+ onStart
RESUMEDFragment is active, interacting with the user+ onResume
DESTROYEDFragment is destroyed+ onDestroyView, onDestroy, onDetach

FragmentManager moves Fragment between states based on user actions and system events. When adding a Fragment to a container, it sequentially goes through INITIALIZED → CREATED → STARTED → RESUMED. When removing — RESUMED → STARTED → CREATED → DESTROYED.

The CREATED state is special: View may be destroyed (after onDestroyView), but the Fragment itself remains in the CREATED state (after onDestroyView, before onDestroy). This allows FragmentManager to keep the Fragment in memory without a View, which is necessary for surviving screen rotations.

Difference Between Fragment Lifecycle and Activity Lifecycle

Fragment Lifecycle and Activity Lifecycle are closely related but have fundamental differences. Fragment always lives inside an Activity, and its lifecycle depends on the host Activity, but is not identical to it.

AspectActivityFragment
Number of callbacks7 (onCreate … onDestroy)11 (onAttach … onDetach)
Separate Lifecycle for ViewNoYes (viewLifecycleOwner)
Survives rotationNo (is destroyed)Yes (ViewModel + Fragment survive)
Host dependencyNoDepends on Activity Lifecycle
State savingonSaveInstanceStateonSaveInstanceState (fragment-level)
ManagementSystemFragmentManager

The main practical difference: on screen rotation, Activity is completely destroyed (onDestroy) and recreated (onCreate). Fragment during rotation goes through onDestroyView (View destroyed) → onCreateView (View recreated), but the Fragment itself and its ViewModel remain alive. This makes Fragment an ideal container for UI logic that needs to survive configuration changes.

Callback order during screen rotation: Activity.onPause → Fragment.onPause → Activity.onStop → Fragment.onStop → Activity.onDestroy → Fragment.onDestroyView → (Activity destroyed) → Activity.onCreate → Fragment.onAttach → Fragment.onCreate → Fragment.onCreateView → Fragment.onViewCreated → Activity.onStart → Fragment.onStart → Activity.onResume → Fragment.onResume.

FragmentManager: State Management and Transactions

FragmentManager is the central class responsible for adding, removing, replacing fragments and managing their states. FragmentManager maintains the BackStack and ensures correct callback ordering during transactions. Each Activity and each nested Fragment has its own FragmentManager.

Main FragmentManager operations:

  • beginTransaction() — opens a transaction for a group of operations.
  • add() — adds a Fragment to a container. Fragment goes through full lifecycle up to RESUMED.
  • replace() — replaces the current Fragment with a new one. Equivalent to remove() + add().
  • remove() — removes a Fragment. Fragment goes through lifecycle from RESUMED to DESTROYED.
  • hide()/show() — hides/shows Fragment without destroying the View. Fragment transitions to STARTED on hide, back to RESUMED on show.
  • detach()/attach() — detaches/reattaches Fragment. detach destroys View (onDestroyView), attach recreates it (onCreateView).
  • addToBackStack() — adds the transaction to BackStack for backward navigation.

BackStack is FragmentManager's transaction stack. When the system Back button is pressed, the last transaction in BackStack is rolled back (popBackStack()). A Fragment removed via popBackStack is restored. If BackStack is empty, pressing Back finishes the Activity.

According to Google, 78% of Fragment issues (duplication, empty screens, IllegalStateException) are related to incorrect FragmentManager usage. The main rule: execute transactions via commit() (asynchronously) or commitNow() (synchronously) depending on context. commit() ensures correct ordering under multiple transactions.

Fragment State Saving: onSaveInstanceState

Fragment supports its own state saving mechanism via onSaveInstanceState, which works independently of Activity. Fragment saves state in a Bundle that is passed to onCreate and onCreateView during restoration.

When Fragment saves state:

  • On screen rotation — View is destroyed, Fragment saves state in Bundle.
  • When Fragment is reattached to Activity after process death.
  • When onSaveInstanceState is called from Activity (the system propagates saving to all child fragments).

Modern approach: use SavedStateHandle in ViewModel to save Fragment state. SavedStateHandle automatically saves and restores data on screen rotation and process death, without requiring manual onSaveInstanceState. Google recommends SavedStateHandle as the preferred way to save UI state in Fragment.

setRetainInstance (deprecated since Fragment 1.3): previously Fragment could be retained via setRetainInstance(true) on screen rotation. This approach has been replaced by ViewModel + SavedStateHandle, which work more reliably and require no special configuration.

viewLifecycleOwner: Separate View Lifecycle

viewLifecycleOwner is a Lifecycle tied to the Fragment View (from onCreateView to onDestroyView). This is a fundamentally important concept: subscriptions to LiveData/Flow made via viewLifecycleOwner are automatically canceled when the View is destroyed (onDestroyView), but do not affect the Fragment itself.

Difference between viewLifecycleOwner and Fragment lifecycle:

  • lifecycle (Fragment) — lives from onAttach to onDetach. Subscriptions remain active even after View destruction.
  • viewLifecycleOwner — lives from onCreateView to onDestroyView. Subscriptions are canceled on View destruction.

Why this matters: if you subscribe to LiveData via Fragment lifecycle (this), after onDestroyView the subscription remains active and LiveData will try to update a null View, causing NPE. Subscribing via viewLifecycleOwner guarantees that after onDestroyView no UI updates will occur.

Rule: in Fragment, always use viewLifecycleOwner for subscriptions to LiveData, Flow, and UI-related coroutines. For ViewModel coroutines, use viewModelScope — it is tied to ViewModel, not to Fragment.

Fragment Code Examples in Kotlin

Example 1: Basic Fragment with onViewCreated and viewLifecycleOwner

Demonstrates correct UI initialization and LiveData subscription via 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", "Updating list: ${users.size} users")
        }
    }

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

Fragment inflates the layout in onCreateView, configures UI and subscribes to LiveData in onViewCreated. Subscription via viewLifecycleOwner is a mandatory requirement to prevent leaks. onDestroyView logs View destruction — confirmation that Fragment survives screen rotation.

Example 2: Fragment with FragmentManager and Transactions

Demonstrates adding Fragment via FragmentManager in Activity, replacement with BackStack and restoration.

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", "Loading user details: $userId")
    }
}

Activity uses supportFragmentManager to manage fragments. The add() transaction with BackStack ensures that on Back press HomeFragment is restored. openDetail() replaces the current Fragment with DetailFragment with arguments. The check for savedInstanceState == null prevents fragment duplication on screen rotation.

Example 3: Fragment with LifecycleObserver and StateFlow

Using Flow and StateFlow in Fragment with viewLifecycleOwner for reactive UI updates.

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", "Search results: ${results.size}")
            }
        }
    }

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

Fragment uses View Binding for View access. The viewLifecycleOwner.lifecycleScope.launch coroutine is automatically canceled when View is destroyed. Binding is nullified in onDestroyView to prevent leaks. StateFlow ensures data freshness when View is recreated.

Frequently Asked Questions

How is onViewCreated different from onCreateView?

onCreateView creates and returns the root Fragment View. onViewCreated is called immediately after View creation, guaranteeing that the View is fully initialized and ready for configuration (findViewById, subscriptions). Google recommends only inflating the layout in onCreateView, and doing all UI configuration in onViewCreated.

When is Fragment actually destroyed — onDestroy or onDetach?

onDestroy — Fragment is destroyed as an object (ViewModel is cleared, coroutines are canceled). onDetach is the last callback, after which Fragment detaches from the Activity. Practically all resources should be released in onDestroyView (View) and onDestroy (Fragment). onDetach is for cleaning up references to the Activity.

Why does Fragment disappear after screen rotation?

Fragment disappears if it was not added to FragmentManager via a transaction with BackStack preservation or if Activity does not restore FragmentManager in onCreate. Solution: add Fragment programmatically via supportFragmentManager.beginTransaction().add() in onCreate with a savedInstanceState == null check.

Can a Fragment exist without an Activity?

No. Fragment is always tied to an Activity via FragmentManager. Even on screen rotation, Activity is recreated and Fragment is reattached to the new Activity. Creating a Fragment outside an Activity is impossible — Fragment constructor requires an empty constructor for system restoration.

What are nested fragments and why are they needed?

Nested fragments are Fragments inside another Fragment. They are used for building complex screens: tab panels, tabbed panels, master-detail. Nested fragments are managed by the child FragmentManager (childFragmentManager). Google recommends not exceeding 2 levels of nesting to avoid performance issues.

Summary

  • Fragment Lifecycle includes 11 callbacks: onAttach → onCreate → onCreateView → onViewCreated → onStart → onResume → onPause → onStop → onDestroyView → onDestroy → onDetach.
  • FragmentManager manages Fragment states (INITIALIZED → CREATED → STARTED → RESUMED → DESTROYED) and transaction BackStack.
  • Fragment survives screen rotation — View is destroyed (onDestroyView), but Fragment and ViewModel remain alive.
  • viewLifecycleOwner is a separate Lifecycle for Fragment View; mandatory for LiveData and UI coroutine subscriptions.
  • Fragment state saving — via onSaveInstanceState or SavedStateHandle in ViewModel.
  • Fragment transactions are executed via FragmentManager with commit() (asynchronously) or commitNow() (synchronously).
  • Always nullify binding and View references in onDestroyView to prevent memory leaks.

We will develop a mobile application turnkey

IT Sectr creates iOS and Android applications for startups and businesses since 2017. We will advise you and propose the best solution.

Discuss the project

Read also