Development of modern mobile applications for the Android platform requires flexibility in building the user interface. The main tool for solving this problem is Fragment a modular part of the UI, which has its own life cycle and can be added or removed during the operation of the application. Understanding how to add a fragment in Android Studio is a critical skill for any developer who wants to create responsive apps that run on both smartphones and tablets.
Unlike Activitya fragment cannot stand on its own and must be placed inside an activity or another fragment. This allows developers to create dynamic interfaces where content can change without completely reloading the screen. For example, on a tablet in landscape orientation, you can display a list of articles on the left and their content on the right, using two different fragments in one activity.
In this article, we will take a detailed look at the process of introducing fragments into your project. We'll look at creating a class, laying out XML markup, and ways to add a component both statically and dynamically through code. Once you master these techniques, you can significantly improve the navigation and user experience in your applications.
Fragment Architecture Basics in Android
Before moving on to practical implementation, you need to understand the theoretical basis. Fragment represents the behavior or part of the user interface in an activity. You can combine multiple fragments into a single activity to build a multi-panel user interface, and reuse a fragment across multiple activities.
From a lifecycle perspective, a fragment is tightly coupled to the activity that hosts it. When an activity enters a onPause()state, all fragments in that activity also enter that state. This is important to consider when dealing with resource-intensive operations or network requests.
โ ๏ธ Attention: Starting with AndroidX, the fragment support library has been updated. Make sure that your projectbuild.gradleenables the dependencyandroidx.fragment:fragmentto avoid compatibility errors on older OS versions.
Using fragments allows you to solve the problem of Android screen fragmentation. Instead of creating separate layouts for phones and tablets, you can combine the same fragments in different ways. This makes the code cleaner and more maintainable.
Use Fragments to create modular UI components that can be easily tested independently of the Activity.
Creating a fragment class and XML markup
The adding process begins with creating a structure. In Android Studio, this is done through the create a new component menu. You need to create two main elements: a markup file (XML) and a Kotlin (or Java) class that will manage the logic.
First, let's create an XML file. In the project structure, go to the folder res/layout, right-click and select New -> Layout Resource File. Name the file, for example fragment_main.xml. Inside this file the visual part of your interface will be described.
<?xml version="1.0" encoding="utf-8"?><FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainFragment">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Hello, this is my first fragment!" />
</FrameLayout>
Now let's create a class. Right-click on the folder java (or kotlin) of your package, select New -> Fragment -> Fragment (Blank). Name the class MainFragment. Android Studio will automatically generate the code template. Pay attention to the method onCreateViewthat returns inflated XML markup.
Inside the class you can work with View elements.
โ๏ธ Creating a fragment structure
Statically adding a fragment in XML
The easiest way to add a fragment is to use a static declaration in the activity XML file. This method is suitable for cases where the fragment should always be visible and its replacement is not required at runtime. To do this, use a special tag <fragment>.
Open the file activity_main.xml. Where you want your component to appear, add a fragment tag. The key attribute here is android:name, which points to the full classpath of your fragment.
<fragmentandroid:id="@+id/my_fragment"
android:name="com.example.myapp.MainFragment"
android:layout_width="match_parent"
android:layout_height="match_parent" />
When using a static method, you will not be able to remove or replace the fragment programmatically at runtime. The Activity itself manages its life cycle. If you need dynamics, this method will not work.
โ ๏ธ Attention: When adding statically, make sure that the fragment class has a public no-argument constructor. Otherwise, the system will not be able to recreate the fragment after rotating the screen or saving the state.
Static addition is convenient for simple screens where the interface structure is fixed. However, modern applications more often require the flexibility that dynamic management provides.
Dynamic management via FragmentManager
Dynamic appending allows you to change content on the fly, which is the basis for navigation in modern applications. To manage fragments, an object is used FragmentManager, which can be obtained from the activity through the property supportFragmentManager.
To perform operations (adding, replacing, deleting), a transaction (FragmentTransaction) is used. You start a transaction, perform the necessary actions and end it with a call commit(). This ensures that the changes are applied atomically.
val fragmentManager = supportFragmentManagerval fragmentTransaction = fragmentManager.beginTransaction()
val fragment = MainFragment()
fragmentTransaction.add(R.id.fragment_container, fragment, "main_tag")
fragmentTransaction.commit()
In the code above R.id.fragment_container is the ID of the container in the XML activity (usually FrameLayout) where the fragment will be placed. The method add adds a fragment without deleting the previous ones, if any. The replace method removes all existing fragments in the container before adding a new one.
An important aspect of dynamic control is Back Stack. If you want the user to be able to return to the previous state of a fragment by clicking the back button, add a call addToBackStack(null) before commit().
What is the difference between add and replace?
The add method puts a new fragment on top of the old one (the old one remains in memory, but can be hidden). The replace method completely destroys the old fragments in the container and creates a new one. Replace is more memory efficient, but add is faster when switching.
Working with containers and navigation
For dynamic fragments, a container must be defined in the activity XML. It is most often used for this FrameLayout, since it is designed to display one child element, which is ideal for changing screens.
Navigation between fragments is a complex process, which in modern realities is best implemented through a library Navigation Component. It takes on Back Stack management, argument passing, and deep linking. However, understanding manual control through FragmentManager is necessary to understand internal processes.
When passing data to a fragment, use Bundle. Do not create new instances of fragments using a constructor with parameters, as data may be lost when the activity is recreated. Use a static method newInstance.
companion object {fun newInstance(param: String): MainFragment {
val fragment = MainFragment()
val args = Bundle()
args.putString("KEY_PARAM", param)
fragment.arguments = args
return fragment
}
}
Using arguments allows you to preserve the state of the fragment even if Android kills the application process to free up memory. The system will automatically save the Bundle and restore it the next time you start it.
Always use Bundle to pass data to the fragment to ensure correct operation when the device configuration changes.
Comparison of methods and characteristics table
The choice between a static and dynamic approach depends on the requirements of your application. The static method is easier to implement, but limited in capabilities. Dynamic requires more code, but gives full control.
Below is a table comparing the main characteristics of the two approaches to implementing UI components.
| Characteristics | Static (XML) | Dynamic (Code) |
|---|---|---|
| Flexibility | Low (fixed during compilation) | High (changes at runtime) |
| Back Stack management | Automatic (Activity) | Manual (via transactions) |
| Implementation complexity | Low | Medium/High |
| Memory usage | Depends on the Activity | Controlled (can be deleted) |
It is also worth noting that dynamic addition allows you to implement complex transition animations. You can set custom animations for fragments to appear and disappear, which makes the interface more lively.
โ ๏ธ Attention: Android APIs are updated frequently. Methods for working with FragmentManager may change in new versions of the SDK. Always check the Android Developers documentation for your target API version.
Common errors and optimization recommendations
When working with fragments, beginners often make common mistakes. One of them is an attempt to access the View of a fragment before it has been created. This leads to NullPointerException. Always check that the fragment is attached and its views are initialized.
Another problem is memory leaks. If you store a reference to Context or View in a static variable or singleton, the fragment cannot be garbage collected. Use requireContext() or requireView() only when you are sure that the context is present.
To optimize performance, avoid heavy calculations in the method onCreateView. This method should return the UI as quickly as possible. It is better to move heavy logic into a ViewModel or use coroutines.
Why is the fragment not displayed?
A common reason is that you forgot to call commit() on a transaction or use a container ID that is not found in the activity layout. Also check whether the fragment is visually hidden (visibility).
Following these rules will help you create stable and fast applications. Fragments are a powerful tool, and their correct use distinguishes a professional developer from an amateur.
Questions and answers (FAQ)
What is the difference between add() and replace() when adding a fragment?
Method add() adds a new fragment to container without deleting existing ones (they can overlap or hide). The method replace() first deletes all fragments located in the container, and only then adds a new one. Replace is most often used for navigating between screens.
How to pass data from an Activity to a Fragment?
The best way is to use Bundle and method setArguments() before adding the fragment. Inside the fragment, data is retrieved via requireArguments(). Direct references to an Activity are not recommended due to a violation of the principle of modularity.
What is FragmentTransaction and why do you need it?
FragmentTransaction is a class that allows you to perform a set of operations on fragments (adding, deleting, replacing) as a single atomic operation. This ensures the integrity of the UI state.
Is it possible to nest a fragment inside another fragment?
Yes, these are called Nested Fragments. The parent fragment acts as a container for the child. This is useful for creating complex modular interfaces, such as a ViewPager inside a fragment.