page.title=Fragments @jd:body

Quickview

In this document

  1. Creating fragments
  2. Adding a fragment to an activity
  3. Managing fragments
  4. Handling the lifecycle
  5. Integrating with the activity
  6. Adding menus

Key classes

  1. {@link android.app.Fragment}
  2. {@link android.app.FragmentManager}
  3. {@link android.app.FragmentTransaction}

An {@link android.app.Activity} is always the window in which users interact with your application, but a {@link android.app.Fragment} can be responsible for distinct operations and UI that's embedded in an activity. So, when using fragments, your activity becomes more like a container for fragments that define the activity's behavior and UI.

Fragments have their own set of lifecylce callback methods and recieve their own user input events. A fragment must always be embedded in an activity and the fragment's lifecycle is directly affected by the activity's lifecycle. For example, when the activity is stopped, so are all fragments in it, and when the activity is destroyed, so are all fragments. However, while an activity is active (in the "resumed" lifecycle stage), you can manipulate the lifecycle of each fragment independently. For example, you can add and remove fragments while the activity is active and you can add each fragment to a back stack within the activity—each back stack entry in the activity is actually a record of a "transaction" that occurred with the activity's fragments, so that the user can reverse the transaction with the BACK key (this is discussed more later).

Figure 1. The lifecycle of a fragment (while its activity is running).

Android introduced fragments in Android X.X (API Level HONEYCOMB), with the primary intention to support more dynamic and flexible UI designs on large screen devices, such as tablets. Because a tablet has a much larger screen than a mobile phone, there's more room to interchange UI elements. Fragments allow that without the need for you to start a new activity or manage complex changes to the view hierarchy. By dividing the layout of an activity into fragments, the code that defines your activity becomes more modular and interchangable, allowing you to modify the activity's appearance at runtime and for different types of screens.

For example, a news application can use one fragment to show a list of articles on the left and another fragment to display an article on the right—both fragments appear in one activity, side by side, and each fragment has its own set of lifecycle callback methods and handle their own user input events. Thus, instead using one activity to select an article and another activity to read the article, the user can select an article and read it all within the same activity.

When you use a fragment as a part of your layout, it technically lives within a {@link android.view.View} of the activity's layout and defines its own layout of views. You can insert a fragment into your activity layout by declaring the fragment in the activity's XML layout file, as a {@code <fragment>} element, or from your application code by adding it to an existing {@link android.view.View}. However, a fragment is not required to be a part of the activity layout—you might use a fragment as an invisible worker for the activity (more about that later).

The rest of this document describes how to build your application to use fragments, including how fragments can contribute to the activity options menu and action bar, create context menus, maintain their state when added to the activity's back stack, and more.

Creating a Fragment

An implementation of the {@link android.app.Fragment} class contains code that looks a lot like the code in an {@link android.app.Activity}. In fact, if you're converting an existing Android application to use fragments, you'll move code from your {@link android.app.Activity} implementation into your {@link android.app.Fragment} class implementation, and into some of the same callback methods. A fragment contains callback methods similar to an activity, such as {@link android.app.Fragment#onCreate onCreate()}, {@link android.app.Fragment#onStart onStart()}, {@link android.app.Fragment#onPause onPause()}, and {@link android.app.Fragment#onStop onStop()}.

If you're creating a fragment to be a modular piece of an activity UI, then your implementation of {@link android.app.Fragment} should include most of the same lifecycle callback methods traditionally implemented by the activity to initialize elements of the UI and save and restore state information. Usually, you'll want to implement the following methods:

{@link android.app.Fragment#onCreate onCreate()}
The system calls this when creating the fragment. Within your implementation, you should initialize the essential components of the fragment that should be retained when the fragment is paused or stopped.
{@link android.app.Fragment#onCreateView onCreateView()}
The system calls this when it's time for the fragment to draw its user interface for the first time. To draw a UI for your fragment, you must return a {@link android.view.View} from this method that is the root of your fragment's layout. You can return null if the fragment does not provide a UI.
{@link android.app.Activity#onPause onPause()}
The system calls this method as the first indication that the user is leaving the fragment (though it does not always mean the fragment is being destroyed). This is usually where you should commit any changes that should be persisted beyond the current user session (because the user might not come back).

Most applications should implement at least these three methods for each fragment, but there are several other lifecycle callback methods that you should also use in order to provide the best user experience when switching fragments and when the activity is paused or stopped. All of the lifecycle callback methods are discussed more later, in the section about Handling the Lifecycle.

There are also a few different subclasses of {@link android.app.Fragment} that you might want to use:

{@link android.app.DialogFragment}
Displays a floating dialog. Using this class to create a dialog is a good alternative to using the dialog helper methods in the {@link android.app.Activity} class, because the dialog can be incorporated into the fragment back stack managed by the activity.
{@link android.app.ListFragment}
Displays a list of items that are managed by an adapter (such as a {@link android.widget.SimpleCursorAdapter}), similar to {@link android.app.ListActivity}. Provides methods for managing a list, such as the {@link android.app.ListFragment#onListItemClick(ListView,View,int,long) onListItemClick()} callback to handle click events on list items.
{@link android.preference.PreferenceFragment}
Displays a hierarchy of {@link android.preference.Preference} objects as a list, similar to {@link android.preference.PreferenceActivity}.

However, subclassing the standard {@link android.app.Fragment} class is most common, if you're not creating a dialog, a list, or displaying preferences.

Providing a user interface

To provide a UI layout for a fragment, you must implement the {@link android.app.Fragment#onCreateView onCreateView()} callback method in your {@link android.app.Fragment} (unless your fragment is a subclass of {@link android.app.ListFragment}, which returns a {@link android.widget.ListView} from this method by default). The Android system calls {@link android.app.Fragment#onCreateView onCreateView()} when it's time for the fragment to draw its layout. Your implementation of this method must return a {@link android.view.View} that is the root of your fragment's layout.

The easiest way to provide your layout is to inflate it from a layout resource. To help you inflate a layout, the {@link android.app.Fragment#onCreateView onCreateView()} method passes a {@link android.view.LayoutInflater} that you can use to get your layout. For example, here's a simple subclass of {@link android.app.Fragment} that contains an implementation of {@link android.app.Fragment#onCreateView onCreateView()} that loads the fragment's layout from a resource:

public static class SimpleFragment extends Fragment {
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        // Inflate the layout for this fragment
        return inflater.inflate(R.layout.simple_fragment, container, false);
    }
}

The {@link android.view.LayoutInflater#inflate(int,ViewGroup,boolean) inflate()} method takes three arguments:

The {@code container} parameter passed to {@link android.app.Fragment#onCreateView onCreateView()} provides the parent {@link android.view.ViewGroup} in which your fragment layout will be inserted, which you can use to generate layout parameters for your fragment layout. The {@code savedInstanceState} parameter is a {@link android.os.Bundle} that provides data about the previous instance of the fragment, if the fragment is being resumed (restoring state is discussed more in the section about Handling the Lifecycle.

Adding a Fragment to an Activity

Each fragment is embedded into the layout of its container activity as a part of the overall view hierarchy, whether or not it actually provides a UI. If a fragment is not embedded into the activity layout, then it is never created (it does not receive any lifecycle callbacks). There are two ways you can add a fragment to the activity layout:

Example: simple fragments

In the last couple sections, you saw how to declare layout for a fragment and add it to an activity. What follows is some code that brings it all together, like a "Hello World" for fragments.

First, here's a layout file for a fragment:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >
<TextView  
    android:layout_width="match_parent" 
    android:layout_height="wrap_content"
    android:text="@string/hello" />
<TextView  
    android:layout_width="match_parent" 
    android:layout_height="wrap_content"
    android:text="@string/hello" />
</LinearLayout>

With that file saved at {@code res/layout/simple_fragment.xml}, the following {@link android.app.Fragment} uses it for its layout:

public static class SimpleFragment extends Fragment {
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        // Inflate the layout for this fragment
        return inflater.inflate(R.layout.simple_fragment, null);
    }
}

And the following layout for an activity applies the fragment twice, side by side:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="horizontal"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
    <fragment android:name="com.example.SimpleFragment"
            android:id="@+id/list"
            android:layout_weight="1"
            android:layout_width="0dp"
            android:layout_height="match_parent" />
    <fragment android:name="com.example.SimpleFragment"
            android:id="@+id/viewer"
            android:layout_weight="1"
            android:layout_width="0dp"
            android:layout_height="match_parent" />
</LinearLayout>

That's it. When an activity applies the previous layout as its content, the {@code SimpleFragment} class is instantiated for each occurence in the layout, applying the fragment layout when it receives the call to {@link android.app.Fragment#onCreateView onCreateView()}.

Although the fragment in this example implements only the {@link android.app.Fragment#onCreateView onCreateView()} callback, there are several other lifecycle callback methods that you should implement in your application. For example, {@link android.app.Fragment#onCreate onCreate()}, {@link android.app.Fragment#onPause onPause()}, {@link android.app.Fragment#onStop onStop()} and others that coincide with the fragment's lifecycle.

Managing Fragments

A useful feature of fragments is the ability to add, remove, replace, and perform other operations on a fragment as the user interacts with the activity, alowing for more rich user experiences without changing activities. In order to perform these operations, you must use {@link android.app.FragmentTransaction} to perform fragment "transactions." You can acquire {@link android.app.FragmentTransaction} from your activity with {@link android.app.Activity#openFragmentTransaction}.

Common transactions you can perform with fragments include:

{@link android.app.FragmentTransaction#add add()}
Add a {@link android.app.Fragment} to the {@link android.app.Activity} layout.
{@link android.app.FragmentTransaction#remove remove()}
Remove a {@link android.app.Fragment} from the {@link android.app.Activity} layout.
{@link android.app.FragmentTransaction#replace replace()}
Replace an existing {@link android.app.Fragment} with another one.

For every transaction (or set of transactions) you perform, you must call {@link android.app.FragmentTransaction#commit} in order for the transactions made with {@link android.app.FragmentTransaction} to be applied. Before you do, however, you can call {@link android.app.FragmentTransaction#addToBackStack} to add the current fragment state to the activity's back stack, so that the user can return to the previous fragment state with the BACK key. For example, here's how a new fragment can replace another one, but keep the previous fragment in the back stack:

// Create new fragment
Fragment newFragment = new MyFragment();
FragmentTransaction ft = openFragmentTransaction();
// Replace and add to back stack
ft.replace(R.id.myfragment, newFragment);
ft.addToBackStack(null);
// Apply changes
ft.commit();

In this example, {@code newFragment} replaces whatever fragment is currently in the layout container identified by the {@code R.id.myfragment} ID. By calling {@link android.app.FragmentTransaction#addToBackStack addToBackStack()}, this transaction (the replace) is saved to the activity's back stack so that the user can reverse this change and bring back the previous fragment by pressing the BACK key.

If you perform multiple transactions and call {@link android.app.FragmentTransaction#addToBackStack addToBackStack()}, then all transactions performed before {@link android.app.FragmentTransaction#commit} are added to the activity's back stack as a single event and the BACK key will reverse them all together.

Handling the Lifecycle

A fragment has a lifecycle that corresponds to the lifecycle of the activity in which it resides. For example, a fragment has callback methods {@link android.app.Fragment#onCreate onCreate()}, {@link android.app.Fragment#onStart onStart()}, {@link android.app.Fragment#onPause onPause()}, {@link android.app.Fragment#onStop onStop()}, and more.

The lifecycle of the activity directly affects the lifecycle of the fragment, such that each lifecycle callback for the activity results in a similar callback for each fragment (for example, when the activity receives {@link android.app.Activity#onPause}, each fragment receives {@link android.app.Fragment#onPause}). However, the fragment's lifecycle can also change independently—but only while the activity is resumed (while it is in the foreground)—because you can dynamically add, remove, and replace fragments without any change to the lifecycle of the activity.

To accomodate backward navigation with the BACK key, you can optionally maintain a back stack of fragment transactions, as described in the previous section. So, if you replace one fragment with another, the user can press the BACK key and view the previous fragment. Additionally, each fragment can maintain its own state, such that when the user navigates back to a previous fragment, the state of that fragment can be restored in the same manner as the state of an activity is restored when it is stopped and restarted.

Managing the lifecycle of a fragment is a lot like managing the lifecycle of an activity. A fragment and an activity both have an "resumed," "paused," and "stopped" state, and they can both retain their state using a {@link android.os.Bundle}. The only significant difference is that an activity is placed into a the task's back stack by default (so that the user can navigate to the previous activity with the BACK key), but a fragment is placed into the activity's back stack only when you explicitly call {@link android.app.FragmentTransaction#addToBackStack(String) addToBackStack()} before you {@link android.app.FragmentTransaction#commit()} a fragment transaction.

The order in which you perform transactions with {@link android.app.FragmentTransaction} doesn't matter, except:

If you do not call {@link android.app.FragmentTransaction#addToBackStack(String) addToBackStack()} when you perform a transaction that removes a fragment, then that fragment is destroyed when the transaction is committed.

Coordinating with the activity lifecycle

The lifecycle of an activity directly affects the lifecycle of a {@link android.app.Fragment} embedded in that activity. The {@link android.app.Fragment} class has lifecycle callback methods that match those in the {@link android.app.Activity} class.

Fragments have a few extra lifecycle callbacks, however, that handle unique interaction with the activity in order to perform actions such as build and destroy the fragment's UI. These additional callback methods are:

{@link android.app.Fragment#onAttach onAttach()}
Called when the fragment has been associated with the activity (the {@link android.app.Activity} is passed in here).
{@link android.app.Fragment#onCreateView onCreateView()}
Called to create the view hierarchy associated with the fragment.
{@link android.app.Fragment#onActivityCreated onActivityCreated()}
Called when the activity's own {@link android.app.Activity#onCreate onCreate()} has finished.
{@link android.app.Fragment#onDestroyView onDestroyView()}
Called when the view hierarchy associated with the fragment is being removed.
{@link android.app.Fragment#onDetach onDetach()}
Called when the fragment is being disassociated from the activity.

The flow of a fragment's lifecycle, as it is affected by its container activity, is illustrated by figure 3. In this figure, you can see how each successive state of the activity determines which callback methods the fragment may receive. For example, when the activity has received its {@link android.app.Activity#onCreate onCreate()} callback, the fragment receives no more than the {@link android.app.Fragment#onActivityCreated onActivityCreated()} callback. However, once the activity reaches the resumed state, you can freely add and remove fragments to the activity, so the fragment lifecycle is no longer inhibitted by the state of the activity. Yet, when the activity leaves the resumed state, the fragment again is pushed through its lifecycle by the activity (unless you explicitly destroy the fragment sooner).

Figure 3. The activity lifecycle's affect on the lifecycle of a fragment.

Integrating with the Activity

Although a {@link android.app.Fragment} is implemented separate from an {@link android.app.Activity} and can be used inside multiple activities, a fragment is directly tied to its container activity and can access the Activity instance with {@link android.app.Fragment#getActivity()}. So, a fragment can easily perform tasks such as find a view in the activity:

View listView = {@link android.app.Fragment#getActivity()}.{@link android.app.Activity#findViewById findViewById}(R.id.list);

This makes it easy for your fragment to call public methods in the activity.

Likewise, your activity can call public methods in the fragment when you have a reference to the {@link android.app.Fragment}. You can acquire a reference to the fragment with {@link android.app.Activity#findFragmentById findFragmentById()} and cast it to your implementation of {@link android.app.Fragment}. For example:

MyFragment fragment = (MyFragment) findFragmentById(R.id.myfragment);
fragment.refreshList();

Creating event callbacks to the activity

In some cases, you might need a fragment to share events with the activity. A good way to do that is to define a callback interface inside the fragment and require that the host activity implement it. When the activity receives a callback, it can share the information with other fragments in the layout as necessary.

For example, if a news application has two fragments in an activity—one to show a list of articles (fragment A) and another to display an article (fragment B)—then fragment A must tell the activity when a list item is selected so that it can tell fragment B to display the article. In this case, the following interface is defined inside fragment A:

public static class FragmentA extends ListFragment {
    ...
    // Container Activity must implement this interface
    public interface SelectedCallback {
        public void onArticleSelected(Uri articleUri);
    }
    ...
}

Then the activity that hosts the fragment implements the {@code SelectedCallback} interface and overrides {@code onArticleSelected()} to notify fragment B of the event from fragment A. To ensure that the host activity implements this interface, fragment A's {@link android.app.Fragment#onAttach onAttach()} callback method (called when the fragment is added to the activity) instantiates an instance of {@code SelectedCallback} by casting the {@link android.app.Activity} that is passed into {@link android.app.Fragment#onAttach onAttach()}:

public static class FragmentA extends ListFragment {
    ...
    @Override
    public void onAttach(Activity activity) {
        super.onAttach(activity);
        try {
            mCallback = (SelectedCallback) activity;
        } catch (ClassCastException e) {
            activity.finish();
            throw new ClassCastException(activity.toString() + " must implement SelectedCallback");
        }
    }
    ...
}

If the activity has not implemented the interface, then a {@link java.lang.ClassCastException} is thrown and the activity is shut down. On success, the {@code mCallback} member holds a reference to the {@link android.app.Activity}, so that fragment A can share events with the activity by calling methods defined by the {@code SelectedCallback} interface. For example, if fragment A is an extension of {@link android.app.ListFragment}, each time the user clicks a list item, the system calls {@link android.app.ListFragment#onListItemClick onListItemClick()} in the fragment, which then calls {@code onArticleSelected()} to share the event with the activity:

public static class FragmentA extends ListFragment {
    ...
    @Override
    public void onListItemClick(ListView l, View v, int position, long id) {
        // Append the clicked item's row ID with the content provider Uri
        Uri noteUri = ContentUris.{@link android.content.ContentUris#withAppendedId withAppendedId}(ArticleColumns.CONTENT_URI, id);
        // Send the event and Uri to the host activity
        mCallback.onArticleSelected(noteUri);
    }
    ...
}

The {@code id} parameter passed to {@link android.app.ListFragment#onListItemClick onListItemClick()} is the row ID of the clicked item, which the activity (or other fragment) uses to fetch the article from the application's {@link android.content.ContentProvider}.

More information about using a content provider is available in the Content Providers document.

Your fragments can contribute action items to the activity's action bar (and menu items to the options menu) using the callback methods {@link android.app.Fragment#onCreateOptionsMenu(Menu,MenuInflater) onCreateOptionsMenu()}. In order for this method to receive calls, however, you must call {@link android.app.Fragment#setHasOptionsMenu(boolean) setHasOptionsMenu()} during the {@link android.app.Fragment#onCreate(Bundle) onCreate()} callback in order to indicate that the fragment would like to receive a call to {@link android.app.Fragment#onCreateOptionsMenu(Menu,MenuInflater) onCreateOptionsMenu()}. Any action or menu items that you add from the fragment are appended to the existing items for the options menu (including those added by other fragments in the activity). The fragment also receives item-selected events with the {@link android.app.Fragment#onOptionsItemSelected(MenuItem) onOptionsItemSelected()} callback method.

The {@link android.app.Fragment} class also contains methods to handle context menus. You can register a view to provide a context menu with {@link android.app.Fragment#registerForContextMenu(View) registerForContextMenu()}. When the user opens the context menu, the fragment receives a call to {@link android.app.Fragment#onCreateContextMenu(ContextMenu,View,ContextMenu.ContextMenuInfo) onCreateContextMenu()}. When the user selects an item, the fragment receives a call to {@link android.app.Fragment#onContextItemSelected(MenuItem) onContextItemSelected()}.

For more information, see Creating Menus and Using the Action Bar.