Table of Contents
Introduction
Fragments are modular pieces of your app’s user interface and behavior that you can combine and reuse inside activities. They help you break a screen into smaller, manageable parts, and they are essential for building flexible UIs that work well on phones and tablets. In a modern Android app, almost every complex screen is composed of one or more fragments.
In this chapter you will get an overview of what fragments are, why they exist, and how they fit into the overall app structure. Details about the fragment lifecycle, fragment transactions, and fragment communication will come in their own dedicated chapters, so here we focus on the general idea and basic usage.
What Is a Fragment
A fragment is a portion of UI with its own layout and logic that lives inside an activity. You can think of it as a small, reusable controller for a piece of screen. Like an activity, a fragment has a lifecycle, can handle user input, and can interact with data and other components. Unlike an activity, a fragment cannot exist on its own. It must be hosted by an activity.
In practice, a fragment is a Kotlin class that usually extends Fragment. It is typically associated with an XML layout file. The fragment is responsible for inflating that layout and controlling what happens in that part of the screen, for example responding to button clicks or updating a list of items.
A single activity can host one fragment or multiple fragments at the same time. The activity coordinates them and decides where each fragment appears on the screen.
A fragment cannot run by itself. It must always be attached to an activity.
Why Fragments Exist
Before fragments existed, each screen of an app was usually implemented as a separate activity. This approach works for simple apps, but it becomes hard to maintain when screens become more complex, especially when you want different layouts for phones and tablets.
Fragments were introduced to solve several problems: code reuse, flexible screen layouts, and better separation of concerns. With fragments, you can build one piece of UI once and reuse it across different activities or in different configurations.
You also gain more control over how your UI adapts. On a phone you might show one fragment per screen, while on a tablet you can show multiple fragments side by side in the same activity. The fragments stay the same, only the way they are arranged changes.
Fragments and Activities
The relationship between fragments and activities is central to how they work. The activity is the host. It provides the window on which your fragments are drawn and manages the overall navigation and high level lifecycle. The fragments provide specific parts of the user interface and logic.
The activity decides which fragments are visible, in what order, and in which containers. For example, your MainActivity might manage a fragment that shows a list of items and another fragment that shows the details of the selected item. On a phone, it can show only the list fragment first, then replace it with the details fragment when the user taps an item. On a tablet, it can show both fragments at the same time.
Fragments communicate with the activity, and the activity may pass data to fragments or trigger fragment changes. The details of this communication are covered in a later chapter, but at a high level the activity acts as a controller that coordinates the different pieces.
Defining a Fragment Class and Layout
To use a fragment, you normally create a Kotlin class that extends Fragment and provide a layout resource for it. A common pattern is to pass the layout resource ID to the Fragment constructor and then use it inside the fragment.
Here is a simple example of a fragment class with an XML layout:
// SimpleFragment.kt
class SimpleFragment : Fragment(R.layout.fragment_simple)The associated XML layout might look like this:
<!-- res/layout/fragment_simple.xml -->
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center">
<TextView
android:id="@+id/messageText"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Hello from Fragment" />
</LinearLayout>
The fragment owns this layout. It can find views inside it using methods such as view.findViewById(...) and update them as needed.
Adding Fragments to an Activity Layout
There are two main ways to put fragments into an activity: statically in XML or dynamically in code. The exact mechanics of transactions and lifecycle are discussed later, but here you see how it generally looks.
Static addition means you declare the fragment directly in the activity’s layout XML. This approach is straightforward when you know at design time which fragment you want to show and you do not need to replace it at runtime.
A typical layout that includes a fragment statically might be:
<!-- res/layout/activity_main.xml -->
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/mainContainer"
android:layout_width="match_parent"
android:layout_height="match_parent">
<fragment
android:id="@+id/simpleFragment"
android:name="com.example.app.SimpleFragment"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</FrameLayout>
In this case Android creates and attaches SimpleFragment to the activity automatically when the activity’s layout is inflated.
Dynamic addition means you use code inside the activity to add, remove, or replace fragments at runtime. This is how you implement navigation within an activity, such as switching from a list fragment to a detail fragment in response to user actions.
An example of adding a fragment programmatically is:
class MainActivity : AppCompatActivity(R.layout.activity_main) {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
if (savedInstanceState == null) {
val fragment = SimpleFragment()
supportFragmentManager.beginTransaction()
.add(R.id.mainContainer, fragment)
.commit()
}
}
}
The container view, here mainContainer, is usually a FrameLayout or another layout that acts as a placeholder where fragments can appear.
Reuse and Flexibility
One of the biggest advantages of fragments is reusability. When you design your app with fragments in mind, you can use the same fragment in different activities, or in different parts of the same activity, without rewriting the logic.
For example, suppose you create a UserListFragment that shows a scrollable list of users. This fragment could be used:
In a main screen activity, where it is the primary content.
Inside a tab of a ViewPager to show users as one of several sections.
Side by side with a UserDetailFragment on a tablet layout.
The fragment class stays exactly the same in each case. Only the layout of the hosting activity and the way it arranges the fragments changes. This separation makes your code easier to maintain and test, because each fragment has a clear responsibility and does not depend on how the rest of the screen looks.
Single Activity Apps and Navigation
Modern Android apps often follow a single activity approach. In this style, you have one main activity that hosts multiple fragments and you navigate between screens by changing which fragments are visible, not by starting new activities all the time.
In a single activity app, the activity typically contains a navigation host, and fragments represent the individual destinations or screens. When the user moves from one screen to another, the app replaces one fragment with another, or adds a new fragment on top of the previous one, depending on the navigation pattern.
This approach makes navigation and shared state management simpler. Shared data can be stored in a ViewModel that is scoped to the activity. Different fragments can observe and update this shared state without having to pass large amounts of data around or recreate it every time.
Managing Fragment State and Configuration
Fragments need to respond to a variety of changes, such as the user rotating the device or the system reclaiming memory. Each fragment has its own lifecycle, which is tightly connected to the activity lifecycle but has additional states for when the fragment’s view is created or destroyed.
You will explore the fragment lifecycle in detail in a later chapter. For now it is enough to know that fragments manage two related but distinct things: the fragment instance itself and the fragment’s view hierarchy. The view hierarchy can be created and destroyed multiple times while the fragment object can remain attached to the activity. This design allows fragments to keep state, such as user selections or presenters, even when the UI is temporarily recreated after a configuration change.
Proper handling of these events is essential for a smooth user experience, and modern tools and architecture components help make this easier.
When to Use Fragments
Fragments are most useful when a part of your UI:
Appears in multiple screens or activities.
Needs to be swapped in or out dynamically.
Should be shown side by side with other parts of the UI on larger screens.
Needs its own lifecycle, separate from the activity, for example to handle long running operations or subscriptions in a lifecycle aware way.
In some simple apps, you might not need fragments at all and can work directly with activities. As your app grows and you want a more modular structure, fragments become an important tool for organizing your UI and logic.
Summary
Fragments are modular UI controllers that live inside activities. They provide their own layout and behavior, but they cannot exist independently of an activity. Using fragments you can build flexible, reusable screens that adapt well to different devices and navigation patterns.
You saw how fragment classes and layouts are defined, how they are added to activities either in XML or in code, and how they enable reuse and a single activity architecture. In the following chapters you will look more closely at the fragment lifecycle, how to perform fragment transactions, and how fragments communicate with each other and with their hosting activity.