Module 6 of 20

Fragments (Deep Dive)

Learn how to build modular and dynamic user interfaces using Android Fragments and manage their lifecycles.

Module 6: Fragments (Deep Dive)

Learning Objectives

By the end of this module, you’ll understand:

  • Why Fragments were introduced
  • Activity vs Fragment
  • The Fragment lifecycle
  • FragmentManager
  • Fragment transactions
  • Fragment back stack
  • View lifecycle vs Fragment lifecycle
  • onCreateView() vs onViewCreated()
  • onDestroyView() and memory leaks
  • Communication between Fragments
  • Modern Fragment architecture
  • Common interview questions

1. The Problem Before Fragments

Let’s go back to Android 1.0.

There were only Activities.

Imagine an email app.

Phone:

+----------------------+
| Inbox                |
|----------------------|
| Email 1              |
| Email 2              |
| Email 3              |
+----------------------+

User taps Email 2.

Android launches another Activity.

InboxActivity



EmailDetailActivity

Simple.

Now imagine a tablet.

Large screen:

+----------------------------------------+
| Inbox      | Email Detail              |
|------------|---------------------------|
| Email 1    | Hello...                  |
| Email 2    |                           |
| Email 3    |                           |
+----------------------------------------+

Oops.

Activities occupy the whole screen.

How can one Activity display two independent sections?

It can’t.


2. Google’s Solution

Google introduced Fragments in Android 3.0 (Honeycomb), initially to support tablets.

Instead of:

Activity



Entire Screen

They introduced:

Activity



Container



Multiple Fragments

Like this:

+--------------------------------------+

Activity

+--------------------------------------+

| Fragment A | Fragment B |

+--------------------------------------+

One Activity could now host multiple UI pieces.


3. The House Analogy

This analogy is worth remembering.

Imagine a house.

House



Kitchen



Bedroom



Bathroom

The house exists independently.

The rooms cannot.

Likewise:

Activity



Fragment



Fragment



Fragment

The Activity owns the Fragments.

A Fragment cannot exist without an Activity host.

This is a fundamental rule.


4. Activity vs Fragment

ActivityFragment
Top-level UI controllerModular UI component
Can exist independentlyMust be attached to an Activity
Managed directly by AndroidManaged by the Activity via FragmentManager
Has its own windowShares the Activity’s window
Has a lifecycleHas its own lifecycle plus a separate view lifecycle

That last point is extremely important and explains many Fragment-related bugs.


5. Creating a Fragment

A simple Fragment:

class HomeFragment : Fragment(R.layout.fragment_home)

Or using onCreateView():

class HomeFragment : Fragment() {

    override fun onCreateView(
        inflater: LayoutInflater,
        container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View {

        return inflater.inflate(
            R.layout.fragment_home,
            container,
            false
        )
    }
}

Notice:

You don’t call onCreateView().

Android does.


6. Fragment Lifecycle

Many developers assume the Fragment lifecycle mirrors the Activity lifecycle.

It doesn’t.

Here’s the simplified sequence:

onAttach()



onCreate()



onCreateView()



onViewCreated()



onStart()



onResume()



Running



onPause()



onStop()



onDestroyView()



onDestroy()



onDetach()

The key insight:

A Fragment has two lifecycles:

  1. The Fragment instance lifecycle.
  2. The Fragment’s View lifecycle.

Understanding the distinction is essential.


7. Why Two Lifecycles?

Consider this example.

A Fragment displays a list.

Fragment



RecyclerView

The user navigates away.

With the Navigation Component, the Fragment instance might remain on the back stack, but its view hierarchy is destroyed to free memory.

That means:

Fragment Object

Still Exists



View

Destroyed

When the user returns:

Existing Fragment



New View Created

The same Fragment instance now owns a new view tree.

This is why the view lifecycle exists separately.


8. onAttach()

The Fragment is associated with its host Activity.

Activity



Fragment Attached

At this point:

  • requireActivity() is valid.
  • The Fragment isn’t displaying a UI yet.

9. onCreate()

Initialize Fragment-level state.

Good for:

  • Reading arguments.
  • Creating non-UI objects.
  • Initializing properties that survive view recreation.

Avoid touching views here—they don’t exist yet.


10. onCreateView()

This is where the UI hierarchy is created.

override fun onCreateView(...) : View

Responsibilities:

  • Inflate the layout.
  • Return the root view.

Think of it as:

“Build my UI.”


11. onViewCreated()

One of the most commonly used callbacks.

By now:

Layout



Inflated



Views Exist

Typical work:

  • Set click listeners.
  • Configure RecyclerViews.
  • Observe ViewModel state using the view lifecycle.
  • Initialize adapters.

Why not in onCreateView()?

Because onViewCreated() guarantees the view hierarchy is fully created, separating view inflation from view setup.


12. onDestroyView()

This is arguably the most important Fragment callback.

Imagine:

Fragment



ViewBinding



RecyclerView



ImageViews

User navigates away.

Android destroys the views.

If your Fragment still holds references to those views, you leak memory.

A common pattern with View Binding:

private var _binding: FragmentHomeBinding? = null
private val binding get() = _binding!!

Initialize in onCreateView():

_binding = FragmentHomeBinding.inflate(inflater, container, false)
return binding.root

Then clear it:

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

This allows the old view hierarchy to be garbage collected.


13. FragmentManager

Who creates and destroys Fragments?

Not Android directly.

The host Activity uses a FragmentManager.

Activity



FragmentManager



Fragments

The FragmentManager:

  • Adds Fragments.
  • Removes Fragments.
  • Replaces Fragments.
  • Maintains the Fragment back stack.

Think of it as the Activity’s “Fragment controller.”


14. Fragment Transactions

Changes to Fragments occur through transactions.

Example:

supportFragmentManager.beginTransaction()
    .replace(R.id.container, HomeFragment())
    .commit()

What’s happening?

Current Fragment



Replace



New Fragment

The transaction isn’t applied immediately; it’s scheduled and committed.


15. The Fragment Back Stack

Suppose you navigate:

HomeFragment



ProfileFragment



SettingsFragment

Without adding to the back stack:

Replace



Old Fragment Gone

Press Back:

The Activity closes.

With:

addToBackStack(null)

The sequence becomes:

Settings



Back



Profile



Back



Home

The FragmentManager manages this stack independently of the Activity stack.


16. Passing Data Between Fragments

Many beginners do this:

val fragment = ProfileFragment()
fragment.user = user // ❌

This is unsafe because Android may recreate the Fragment later.

Instead, use arguments:

val fragment = ProfileFragment().apply {
    arguments = bundleOf(
        "userId" to 42
    )
}

Then read them:

val id = requireArguments().getInt("userId")

Today, the Navigation Component’s Safe Args (XML) or strongly typed navigation in Compose provides even safer approaches.


17. Fragment Communication

Imagine:

HomeFragment



ProfileFragment

Should one Fragment call methods on the other directly?

Generally, no.

A better architecture:

Fragment



Shared ViewModel



Fragment

Or:

Fragment



Activity



Fragment

This keeps Fragments loosely coupled.


18. Common Fragment Bugs

Bug 1: Memory Leak

Fragment



ViewBinding



View Destroyed



Binding Still Exists ❌

Solution:

Clear binding in onDestroyView().


Bug 2: Observing with the Wrong Lifecycle

Incorrect:

viewModel.data.observe(this) { ... }

The Fragment may outlive its view.

Correct:

viewModel.data.observe(viewLifecycleOwner) { ... }

Or, with Flow:

viewLifecycleOwner.lifecycleScope.launch {
    viewLifecycleOwner.repeatOnLifecycle(Lifecycle.State.STARTED) {
        viewModel.uiState.collect { ... }
    }
}

Tie UI observation to the view lifecycle, not the Fragment lifecycle.


Bug 3: Doing View Work Too Early

onCreate()



textView.text = "Hello"

Crash.

Views don’t exist yet.

Do view-related work in onViewCreated().


19. Modern Android Architecture

Historically:

Many Activities



One screen each

Then:

One Activity



Many Fragments

Today, with Jetpack Compose:

One Activity



Compose Navigation



Composable Screens

Fragments haven’t disappeared—they’re still common in existing apps, hybrid projects, and certain integrations—but many new Compose-first apps avoid them for screen navigation.

Understanding Fragments remains essential because you’ll encounter them in production codebases for years to come.


Real-World Example

Imagine a shopping app.

MainActivity



HomeFragment



ProductFragment



CartFragment



CheckoutFragment

The Activity hosts navigation, while each Fragment encapsulates a feature.

If the user rotates the device while viewing a product:

  • The Activity is recreated.
  • The Fragment is recreated.
  • The ViewModel can preserve the product data.
  • The view hierarchy is rebuilt.

The user experiences a seamless transition because the lifecycle is handled correctly.


Best Practices

  • Keep Fragments focused on UI logic.
  • Store screen state in a ViewModel, not in the Fragment.
  • Use onCreateView() only to inflate the layout.
  • Use onViewCreated() to initialize and interact with views.
  • Always clear View Binding in onDestroyView().
  • Observe LiveData/Flow with viewLifecycleOwner.
  • Use Fragment arguments for inputs.
  • Avoid direct Fragment-to-Fragment communication.

Mental Model

Think of a Fragment as a reusable UI controller whose view can come and go multiple times during its lifetime.

Fragment Object

        ├─────────────── Lives Longer ───────────────┐
        │                                            │
        ▼                                            ▼
Create View ──► Use View ──► Destroy View ──► Create New View

This single diagram explains why onDestroyView() exists, why viewLifecycleOwner matters, and why many Fragment bugs happen.


Interview Questions

  1. Why were Fragments introduced?
  2. Explain the difference between an Activity and a Fragment.
  3. Why does a Fragment have two lifecycles?
  4. What’s the difference between onCreateView() and onViewCreated()?
  5. Why is onDestroyView() critical when using View Binding?
  6. What is the role of FragmentManager?
  7. How does the Fragment back stack differ from the Activity back stack?
  8. Why shouldn’t Fragments communicate directly?
  9. Why should UI observations use viewLifecycleOwner instead of this?
  10. How has Jetpack Compose changed the role of Fragments?

Next Module: UI Development (XML & Jetpack Compose)

This is where everything we’ve learned comes together.

We’ll cover:

  • How Android renders a screen from XML.
  • The View hierarchy and measure/layout/draw passes.
  • ConstraintLayout, LinearLayout, FrameLayout, and when to use each.
  • Event handling and input processing.
  • View Binding and Data Binding.
  • Jetpack Compose fundamentals.
  • Declarative UI vs imperative UI.
  • State, recomposition, and why Compose is fundamentally different from XML.

This module will connect Android’s lifecycle with the actual UI you build every day, giving you a deep understanding of both the traditional View system and modern Compose.