Android Fragments Tutorial

Posted on Aug 16, 2012 (one year ago). Seen 93,343 times. 10 comments. Permalink Feed
Photo Ken Jones
Marakana, Inc.
Member since Sep 22, 2010
Location: San Francisco
Stream Posts: 5
Tagged as: Android Tutorial

Overview

Android runs on variety of devices, from phones with small screen sizes, to tablets and large-screen TV sets. Fragments in a nutshell represent a smaller part of a user interface that could take a whole screen, or be part of a larger UI. By creating and using fragments, your app can adapt to a variety of devices and screen sizes. In this module, you will get a solid overview of fragments and will learn how to design them, develop them, and use them both statically and dynamically. Topics covered include:

  • What is a fragment: an overview and motivation

  • The compatibility package: targeting pre-Honeycomb devices

  • Fragment lifecycle

  • Creating a fragment class

  • Creating a fragment layout

  • Statically including fragments in an activity

  • Dynamically attaching fragments

  • Handling run-time configuration changes

  • Retaining Fragments Across Activity Re-Creation

  • Using Fragments with no Layouts

  • Finding Fragments

  • Fragment Operations

  • Performing Fragment Transactions

  • Managing the Fragment Back Stack

  • Integrating Fragment Action Bar/Options Menu Items

  • Integrating Fragment Action Bar/Options Menu Items (example)

  • Communication Between the Fragment and the Activity

  • Best Practices: Loose Coupling of Activities and Fragments

  • Best Practices: Define Fragment Interfaces to Invoke Activity Behavior

  • Best Practices: The Activity as a Switchboard

  • Advanced Fragment Initialization

  • Implementing Dialogs Using Fragments

  • Using a Fragment-Based Dialog

  • Fragment-Based Preference Management

  • Additional Fragment Subclasses

So, What’s a Fragment?

A fragment is a class implementing a portion of an activity.

  • A fragment represents a particular operation or interface running within a larger activity.

  • Fragments enable more modular activity design, making it easier to adapt an application to different screen orientations and multiple screen sizes.

  • Fragments must be embedded in activities; they cannot run independent of activities.

  • Most fragments define their own layout of views that live within the activity’s view hierarchy.

    • However, a fragment can implement a behavior that has no user interface component.

  • A fragment has its own lifecycle, closely related to the lifecycle of its host activity.

  • A fragment can be a static part of an activity, instantiated automatically during the activity’s creation.

  • Or, you can create, add, and remove fragments dynamically in an activity at run-time.

Fragments: Implemented in Honeycomb (3.0) or Later

Fragments were added to the Android API in Honeycomb, API 11.

The primary classes related to fragments are:

android.app.Fragment

The base class for all fragment definitions

android.app.FragmentManager

The class for interacting with fragment objects inside an activity

android.app.FragmentTransaction

The class for performing an atomic set of fragment operations

Fragments: Implemented in Donut (1.6) or Later

Google provides the Compatibility Package, a Java library that you can include in an application, implementing support for fragments and other Honeycomb features (loaders).

  • You can use the Compatibility Package with applications targeting 1.6 (API 4) or later.

  • For each of the classes in the Compatibility Package, the APIs work almost exactly the same as their counterparts in the latest Android platform. Therefore, you can usually refer to the online documentation for information about the supported APIs.

Note If you write an application using the Compatibility Package, your application uses the class definitions from the Compatibility Package even when running on a device with 3.0 or later installed. The package does not try to switch to the device’s “native” implementation of the classes.

The primary classes related to fragments are:

android.support.v4.app.FragmentActivity

The base class for all activities using compatibility-based fragment (and loader) features

android.support.v4.app.Fragment

The base class for all fragment definitions

android.support.v4.app.FragmentManager

The class for interacting with fragment objects inside an activity

android.support.v4.app.FragmentTransaction

The class for performing an atomic set of fragment operations

Important To use the Compatibility Package features, your activity must use android.support.v4.app.FragmentActivity as a base class, rather than android.app.Activity or one of its subclasses.

Downloading the Compatibility Package

You can download and install the Compatibility Package using the Android SDK and AVD Manager tool.

  • You can find the Compatibility Package for download under "Android Repository" as "Android Compatibility package".

images/download_compatibility_package.png

Using the Compatibility Package

images/menu_add_compatibility_library.png

To use the Compatibility Package, you must add it to your Android project and include it in your Build Path.

  • Using the Eclipse ADT plugin, you can do this automatically by:

    1. Selecting your Android project in the Package Explorer view

    2. Bringing up the context-menu

    3. Selecting Android Tools → Add Compatibility Library

Fragment Lifecycle

images/activity_fragment_lifecycle.png

As with the Activity class, the Fragment base class is an example of the template method design pattern.

  • The Fragment base class defines a set of methods that you override to provide the custom behavior of your fragment implementation.

Of primary importance are the fragment lifecycle callback methods.

  • The lifecycle of the activity in which the fragment lives directly affects the lifecycle of the fragment.

  • Each lifecycle callback for the activity results in a similar callback for each fragment.

  • For example, when the activity receives onPause(), each fragment in the activity receives onPause().

Fragments have a few extra lifecycle callbacks managing interaction with the activity:

onAttach(Activity)

Called when the fragment has been associated with the activity.

onCreateView(LayoutInflater, ViewGroup, Bundle)

Called to create the view hierarchy associated with the fragment.

onActivityCreated(Bundle)

Called when the activity’s onCreate() method has returned.

onDestroyView()

Called when the view hierarchy associated with the fragment is being removed.

onDetach()

Called when the fragment is being disassociated from the activity.

Important When overriding these lifecycle methods — with the exception of onCreateView() — you must call through to the super class’s implementation of the method. Otherwise, an exception occurs at run-time.

Creating the Fragment Class

Each fragment must be implemented as a subclass of Fragment.

Many of the Fragment methods are analogous to those found in Activity, and you should use them in a similar fashion.

onCreate(Bundle)

Initialize resources used by your fragment except those related to the user interface.

onCreateView(LayoutInflater, ViewGroup, Bundle)

Create and return the view hierarchy associated with the fragment.

onResume()

Allocate “expensive” resources (in terms of battery life, monetary cost, etc.), such as registering for location updates, sensor updates, etc.

onPause()

Release “expensive” resources. Commit any changes that should be persisted beyond the current user session.

Creating a Fragment Layout

To provide a layout for a fragment, your fragment’s class must implement the onCreateView() callback method.

  • The Android system invokes this method when it’s time for the fragment to create its layout.

  • This method must return a View that is the root of your fragment’s layout.

As with an activity, you can create your layout programmatically by directly instantiating and configuring view objects, or declaratively by providing an XML layout file and inflating the layout.

  • The declarative approach usually is simpler and easier.

  • In support of the declarative approach, the system provides a reference to a LayoutInflater and a ViewGroup from the activity’s layout, which will serve as the parent of your fragment’s layout.

Creating a Fragment Layout (example)

For example, you could define a simple layout resource such as this:

res/layout/first_fragment.xml
<?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"
    android:id="@+id/first_fragment_root">

    <TextView android:layout_height="wrap_content"
        android:text="@string/text_first_fragment_title"
        android:layout_width="match_parent"
        android:gravity="center_horizontal" />
    <EditText android:layout_height="wrap_content"
        android:layout_width="match_parent"
        android:id="@+id/edit_first_msg" />
    <Button android:layout_height="wrap_content"
        android:layout_gravity="center_horizontal"
        android:layout_width="wrap_content"
        android:id="@+id/button_first"
        android:text="@string/button_first_text" />

</LinearLayout>

Then to initialize your fragment’s layout:

Fragment source code
public class FirstFragment extends Fragment implements OnClickListener {

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.first_fragment,
                                     container, false);

        Button nextButton = (Button) view.findViewById(R.id.button_first);
        nextButton.setOnClickListener(this);

        return view;
    }

    // ...
}
Note The final false argument to LayoutInflator.inflate() prevents the inflator from automatically attaching the inflated view hierarchy to the parent container. This is important, because the activity automatically attaches the view hierarchy to the parent as appropriate.

“Statically” Including a Fragment in an Activity Layout

The easiest way to incorporate a fragment into an activity is by including it directly into the activity’s layout file.

  • This works well if the fragment should always be present in the layout.

  • However, this approach does not allow you to dynamically remove the fragment at run-time.

In the activity’s layout file, simply use the <fragment> element (yes, that’s really lowercase) where you want to include the fragment.

  • Use the android:name attribute to provide the package-qualified class name of the fragment.

  • Specify the layout attributes to control the size and position of the fragment.

Note

Each fragment requires a unique identifier that the system can use to restore the fragment if the activity is restarted (and which you can use to capture the fragment to perform transactions, such as remove it). There are three ways to provide an ID for a fragment:

  • Supply the android:id attribute with a unique ID.

  • Supply the android:tag attribute with a unique string.

  • If you provide neither of the previous two, the system uses the ID of the fragment’s container view.

For example:

Activity Layout
<?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.news.ArticleListFragment"
            android:id="@+id/list"
            android:layout_weight="1"
            android:layout_width="0dp"
            android:layout_height="match_parent" />
    <fragment android:name="com.example.news.ArticleReaderFragment"
            android:id="@+id/viewer"
            android:layout_weight="2"
            android:layout_width="0dp"
            android:layout_height="match_parent" />
</LinearLayout>

Dynamically Adding a Fragment to an Activity

At any time while your activity is running, you can add fragments to your activity layout.

  1. First, use Activity.getFragmentManager() to get a reference to the FragmentManager.

    Note If you’re using the Compatibility Package, use FragmentActivity.getSupportFragmentManager().
  2. Invoke FragmentManager.beginTransaction() to get an instance of FragmentTransaction.

  3. Instantiate an instance of your fragment.

  4. Use the FragmentTransaction.add() to add the fragment to a ViewGroup in the activity, specified by its ID. Optionally, you can also provide a String tag to identify the fragment.

  5. Commit the transaction using FragmentTransaction.commit().

For example:

Activity source code
FragmentManager fragmentManager = getFragmentManager()
// Or: FragmentManager fragmentManager = getSupportFragmentManager()
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
ExampleFragment fragment = new ExampleFragment();
fragmentTransaction.add(R.id.fragment_container, fragment);
fragmentTransaction.commit();

But… There’s a catch.

Handling Run-Time Configuration Changes

When the system destroys and re-creates an activity because of a run-time configuration change, the activity automatically re-instantiates existing fragments.

  • This isn’t a problem for “static” fragments declared in the activity’s layout.

  • But for “dynamic” fragments, you need to test for this situation to prevent creating a second instance of your fragment.

To test whether the system is re-creating the activity, check whether the Bundle argument passed to your activity’s onCreate() is null.

  • It it is non-null, the system is re-creating the activity. In this case, the activity automatically re-instantiates existing fragments.

  • If it null you can safely instantiate your dynamic fragment. For example:

Activity source code
public void onCreate(Bundle savedInstanceState) {
    // ...
    if (savedInstanceState == null) {
        FragmentManager fragmentManager = getFragmentManager()
        // Or: FragmentManager fragmentManager = getSupportFragmentManager()
        FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
        ExampleFragment fragment = new ExampleFragment();
        fragmentTransaction.add(R.id.fragment_container, fragment);
        fragmentTransaction.commit();
    }
}

Saving Fragment State

The Fragment class supports the onSaveInstanceState(Bundle) method (but not the onRestoreInstanceState() method) in much the same way as the Activity class.

  • The default implementation saves the state of all the fragment’s views that have IDs.

  • You can override this method to store additional fragment state information.

  • If the system is re-creating the fragment from a previous saved state, it provides a reference to the Bundle containing that state to the onCreate(), onCreateView(), and onActivityCreated() methods; otherwise, the argument is set to null.

Retaining Fragments Across Activity Re-Creation

By default, when an activity is re-created (such as in response to a run-time configuration change), its fragments are also destroyed and re-created automatically.

Executing Fragment.setRetainInstance(boolean) with a value of true requests the system to retain the current instance of the fragment if the activity is re-created.

  • If set, when the activity is re-created, the fragment’s onDestroy() and onCreate() methods are not invoked.

  • All other fragment lifecycle methods are invoked in their typical sequence.

    Note If you use setRetainInstance(true), then the Bundle argument to onCreateView() and and onActivityCreated() is null because the fragment is not re-created.

“Retained” fragments can be quite useful for propagating state information — especially thread management — across activity instances.

  • For example, a fragment can serve as a “host” for an instance of Thread or AsyncTask, managing its operation.

  • The Activity.onRetainNonConfigurationInstance() method, which has traditionally been used for this purpose, is deprecated as of API 11 in favor of the fragment’s setRetainInstance() capability.

    Important If you are using the compatibility library, the FragmentActivity class overrides onRetainNonConfigurationInstance() making it final to implement the fragment (and loader) retention capability.

Using Fragments with no Layouts

A fragment is not required to have a user interface.

  • For example, if the sole purpose of a fragment is to maintain state information or manage a thread, it might not need a user interface.

When using a fragment with no user interface:

  • There is no need to override the onCreateView() method.

  • You must add the fragment to the activity using FragmentTransaction.add(Fragment, String), providing a unique String tag to identify the fragment.

  • For example:

Activity source code
FragmentManager fragmentManager = getFragmentManager()
// Or: FragmentManager fragmentManager = getSupportFragmentManager()
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
BackgroundFragment fragment = new BackgroundFragment();
fragmentTransaction.add(fragment, "thread_manager");
fragmentTransaction.commit();

Finding Fragments

The FragmentManager class has methods for finding a fragment contained within an activity:

findFragmentById(int id)

Finds a fragment with the specified ID.

findFragmentByTag(String tag)

Finds a fragment with the specified tag.

Both of these methods return a reference to the fragment, or null if no matching fragment is found.

Fragment Operations

You can perform many other operations on dynamic fragments other than adding them to an activity, such as removing them and changing their visibility.

  • Each set of changes that you commit to the activity is called a transaction.

  • You perform fragment operations using the methods in the FragmentTransaction class. Methods include:

    add()

    Add a fragment to the activity.

    remove()

    Remove a fragment from the activity. This operation destroys the fragment instance unless the transaction is added to the transaction back stack, described later.

    replace()

    Remove one fragment from the UI and replace it with another.

    hide()

    Hide a fragment in the UI (set its visibility to hidden without destroying the view hierarchy).

    show()

    Show a previously hidden fragment.

    detach() (API 13)

    Detach a fragment from the UI, destroying its view hierarchy but retaining the fragment instance.

    attach() (API 13)

    Reattach a fragment that has previously been detached from the UI, re-creating its view hierarchy.

Important You can’t remove(), replace(), detach(), or attach() a “static” fragment declared in an activity’s layout.
Note Revision 3 and later of the Compatibility Package also supports the attach() and detach() methods.

Performing Fragment Transactions

To perform a fragment transaction:

  1. Obtain an instance of FragmentTransaction by calling FragmentManager.beginTransaction().

  2. Perform any number of fragment operations using the transaction instance.

    Tip Most of the FragmentTransaction operations return a reference to the same FragmentTransaction instance, allowing method chaining.
  3. Call commit() to apply the transaction to the activity.

    Important You can commit a transaction using commit() only prior to the activity saving its state (i.e., before the system invokes Activity.onSaveInstanceState()). If you attempt to commit after that point, an exception will be thrown.

For example:

Activity source code
FragmentManager fragmentManager = getFragmentManager()
// Or: FragmentManager fragmentManager = getSupportFragmentManager()
fragmentManager.beginTransaction()
    .remove(fragment1)
    .add(R.id.fragment_container, fragment2)
    .show(fragment3)
    .hide(fragment4)
    .commit();

The order in which you add changes to a FragmentTransaction doesn’t matter, except:

  • You must call commit() last.

  • If you’re adding multiple fragments to the same container, then the order in which you add them determines the order they appear in the view hierarchy.

Managing the Fragment Back Stack

Similar to the way the system automatically mains a task back stack for activities, you have the option of saving fragment transactions onto a back stack managed by the activity.

  • If you add fragment transactions to the back stack, then the user can navigate backward through the fragment changes by pressing the device’s Back button.

  • Once all fragment transactions have been removed from the back stack, pressing the Back button again destroys the activity.

To add a transaction to the back stack, invoke FragmentTransaction.addToBackStack(String) before committing the transaction.

  • The String argument is an optional name to identify the back stack state, or null. The FragmentManager class has a popBackStack() method, which can return to a previous back stack state given its name.

  • If you add multiple changes to the transaction and call addToBackStack(), then all changes applied before you call commit() are added to the back stack as a single transaction and the Back button will reverse them all together.

If you call addToBackStack() when removing or replacing a fragment:

  • The system invokes onPause(), onStop(), and onDestroyView() on the fragment when it is placed on the back stack

  • If the user navigates back, the system invokes onCreateView(), onActivityCreated(), onStart(), and onResume() on the fragment.

Integrating Fragment Action Bar/Options Menu Items

A fragment can add its own items to the activity’s action bar or options menu.

  • First, you must invoke Fragment.setHasOptionsMenu() in the fragment’s onCreate() method.

  • Then you can provide definitions for the fragment’s onCreateOptionsMenu() and onOptionsItemSelected() methods, and optionally onPrepareOptionsMenu(), onOptionsMenuClosed(), and onDestroyOptionsMenu() methods, if needed.

  • You implement these methods exactly as if they appeared within an activity class definition.

The corresponding methods in the Activity base class (or FragmentActivity base class) automatically invoke these methods for each fragment it contains.

  • If you override these methods in your activity class, you can process any menu items managed directly by the activity.

  • Then, if appropriate, invoke the super version of the method to propagate the call to the fragments within the activity. Don’t forget to do this, or your fragment’s items will be ignored!

The activity automatically updates the action bar/options menu based on the dynamic state of its fragments.

  • Items are added if needed when fragments are added, shown, or attached.

  • Items are removed if no longer needed when fragments are removed, hidden, or detached.

Note A fragment that adds items to the options menu does not need to have a view hierarchy. For example, a fragment could add Start and Stop items to the menu to control its behavior, but not display any other user interface.

Integrating Fragment Action Bar/Options Menu Items (example)

Activity source code
public class MyActivity extends Activity {
    // ...

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        super.onCreateOptionsMenu(menu);
        getMenuInflater().inflate(R.menu.activity_options, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        switch (item.getItemId()) {
        case R.id.menu_activity_info:
            // Handle activity menu item
            return true;
        default:
            // Handle fragment menu items
            return super.onOptionsItemSelected(item);
        }
    }

    // ...
}
Fragment source code
public class MyFragment extends Fragment {
    // ...

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setHasOptionsMenu(true);
    }

    @Override
    public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
        inflater.inflate(R.menu.myfragment_options, menu);
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        switch (item.getItemId()) {
        case R.id.menu_first_info:
            // Handle fragment menu item
            return true;
        default:
            // Not one of ours. Perform default menu processing
            return super.onOptionsItemSelected(item);
        }
    }

    // ...
}

Communication Between the Fragment and the Activity

A given instance of a fragment is directly tied to the activity that contains it.

  • Your activity can call public methods in the fragment through a reference to the fragment object.

    • If you don’t retain a reference to a fragment when creating it, you can find it with the FragmentManager, using findFragmentById() or findFragmentByTag().

  • The fragment can access its containing activity instance with the Fragment.getActivity() method.

    • For example, you could obtain a reference to a view in the activity’s layout:

      View listView = getActivity().findViewById(R.id.list);
Note The Fragment class is not derived from Context. If your fragment needs a Context object, either use the activity or — especially if the Context might be retained after activity destruction — invoke getApplicationContext() on the hosting activity.

Best Practices: Loose Coupling of Activities and Fragments

Avoid tight coupling between activities and fragments.

  • Especially if you make the fragment “too aware” of its hosting activity and the other fragments that might (or might not) be present in the activity, you increase its complexity and reduce its reuse.

  • On the other hand, activities typical need more awareness of the fragments they and other activities host.

Best Practices: Define Fragment Interfaces to Invoke Activity Behavior

Define interfaces in fragments to call back to their hosting activities.

  • Rather than having a fragment directly access the internals of a hosting activity, create a nested interface within the fragment defining a set of callback methods.

  • The hosting activity can then implement the interface, or you can provide another listener object that implements the interface.

  • If you plan always to use the activity as an event listener, you can automatically “register” it in the fragment’s onAttach() method. Otherwise, you can provide a listener registration method.

  • For example:

Fragment source code
public class TitlesFragment extends ListFragment {
    private OnTitleSelectedListener listener;

    public interface OnTitleSelectedListener {
        public void onTitleSelected(int index);
    }

    public void setOnTitleSelectedListener(OnTitleSelectedListener listener) {
        this.listener = listener;
    }

    @Override
    public void onListItemClick(ListView l, View v,
                                int position, long id) {
        listener.onTitleSelected(position);
    }

        // ...
}
Activity source code
public class MyActivity extends Activity
    implements TitlesFragment.OnTitleSelectedListener {

        @Override
        public boolean onCreate(Bundle bundle) {
                // ...
                TitlesFragment titles = new TitlesFragment();
                titles.setOnTitleSelectedListener(this);
                // ...
        }

    public void onTitleSelected(int index) {
        // ...
    }
    // ...
}

Best Practices: The Activity as a Switchboard

Let the activity serve as an intermediary between fragments.

  • Fragments don’t have intent filters; an Intent can’t directly trigger a fragment.

  • Let the activity respond to intents and fragment callbacks.

  • The activity will know if it can “route” a event to a fragment it contains, or if it needs to start another activity to handle the event.

Advanced Fragment Initialization

Every fragment must have a default empty constructor.

  • The system invokes the default constructor to re-instantiate the fragment when restoring its activity’s state.

Fragments generally should not implement additional constructors or override the default constructor.

  • The first place application code can run where the fragment is ready to be used is in onAttach().

Advanced Fragment Initialization: Arguments

  • Immediately after instantiating a fragment, can can provide it with a set of arguments.

    • Create a Bundle object, and put in it any values to want to provide as arguments to the fragment.

    • Invoke setArguments(Bundle) on the fragment, passing the Bundle.

  • Within the fragment, invoke getArguments() when you’re ready to retrieve the Bundle of arguments.

  • Often, especially in the case of a fragment supporting only one or two arguments, it’s easiest to define a static factory method to instantiate the fragment and supply the arguments.

Fragment source code
public static class DetailsFragment extends Fragment {
    public static DetailsFragment newInstance(int index) {
        DetailsFragment f = new DetailsFragment();

        // Supply index input as an argument.
        Bundle args = new Bundle();
        args.putInt("index", index);
        f.setArguments(args);

        return f;
    }

    public int getShownIndex() {
        return getArguments().getInt("index", 0);
    }

    // ...
}
Activity source code
DetailsFragment detail = DetailsFragment.newInstance(2);

Implementing Dialogs Using Fragments

As of Honeycomb (API 11), the Activity class’s “managed dialog” methods are deprecated in favor of fragments.

The DialogFragment class serves as a base class for fragment-based dialog management.

  • DialogFragment implements a fragment that displays a dialog window, floating on top of its activity’s window.

  • This fragment contains a Dialog object, which it displays as appropriate based on the fragment’s state.

  • You should control dialog (showing and dismissing it) through the DialogFragment methods, not with direct calls on the dialog.

You can implement a DialogFragment so that it can be used only as a dialog, or so that it can be displayed as either a dialog or as a “normal” fragment managed by a ViewGroup within the activity.

  • If you plan to use the fragment only as a dialog, override the onCreateDialog() method and return an instance of Dialog or one of its subclasses.

  • If you want to use the fragment as either a dialog or a normal fragment, override onCreateView() and return a view hierarchy.

Using a Fragment-Based Dialog

The DialogFragment class provides an overloaded show() method, which posts the dialog as part of a transaction.

  • If provided with a FragmentManager reference, the show() method creates a transaction, adds the fragment, and then commits. When the fragment is dismissed, a new transaction is executed automatically to remove it from the activity.

  • If provided with a FragmentTransaction reference, the show() method adds the fragment and commits the transaction. In this case, you have the option of adding the transaction to the back stack prior to invoking show()

  • In either version, the second argument is a String tag to identify the dialog fragment.

The DialogFragment class provides a dismiss() method to dismiss the fragment explicitly.

  • If the fragment was added to the back stack, all back stack state up to and including this entry is popped. Otherwise, a new transaction is committed to remove the fragment.

  • In the typical use case, the fragment dismisses itself with this method when its dialog is dismissed.

Example: A Simple Confirmation Dialog Fragment

Fragment source code
public class ConfirmationDialogFragment extends DialogFragment
        implements DialogInterface.OnClickListener {

    private ConfirmationDialogFragmentListener listener;

    public static ConfirmationDialogFragment newInstance(int title) {
        ConfirmationDialogFragment frag = new ConfirmationDialogFragment();
        Bundle args = new Bundle();
        args.putInt("title", title);
        frag.setArguments(args);
        return frag;
    }

    public interface ConfirmationDialogFragmentListener {
        public void onPositiveClick();
        public void onNegativeClick();
    }

    public void setConfirmationDialogFragmentListener(
            ConfirmationDialogFragmentListener listener) {
        this.listener = listener;
    }

    @Override
    public Dialog onCreateDialog(Bundle savedInstanceState) {
        int title = getArguments().getInt("title");

        return new AlertDialog.Builder(getActivity())
                .setIcon(android.R.drawable.ic_dialog_alert)
                .setTitle(title)
                .setPositiveButton(android.R.string.ok, this)
                .setNegativeButton(android.R.string.cancel, this)
                .create();
    }

    @Override
    public void onClick(DialogInterface dialog, int which) {
        if (listener != null) {
            switch (which) {
            case DialogInterface.BUTTON_POSITIVE:
                listener.onPositiveClick();
            default:
                listener.onNegativeClick();
            }
        }
    }

}
Activity source code
public class SimpleConfirmationDialogFragmentActivity
    extends FragmentActivity
    implements OnClickListener, ConfirmationDialogFragmentListener {

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        Button buttonPostDialog = (Button) findViewById(R.id.button_post_dialog);
        buttonPostDialog.setOnClickListener(this);
    }

    @Override
    public void onClick(View v) {
        ConfirmationDialogFragment confirmationDialog
            = ConfirmationDialogFragment.newInstance(R.string.dialog_format_title);
        confirmationDialog.setConfirmationDialogFragmentListener(this);
        confirmationDialog.show(getSupportFragmentManager(), null);
    }

    @Override
    public void onPositiveClick() {
        Toast.makeText(this, android.R.string.ok, Toast.LENGTH_LONG).show();
    }

    @Override
    public void onNegativeClick() {
        Toast.makeText(this, android.R.string.cancel, Toast.LENGTH_LONG).show();
    }
}

Additional Fragment Subclasses

There are some additional subclasses of Fragment designed for common uses:

ListFragment

A fragment that automatically manages a ListView. Analogous to the ListActivity class.

WebFragment

A fragment that automatically creates and manages a WebView.

Comments

Posted on Aug 27, 2012
Photo Kiran Gowda
Csr
Member since Aug 27, 2012
Hi,

I am not able to understand what is R.id.fragment_container, could you please explain what it is??
Posted on Aug 27, 2012
Photo Ken Jones
Marakana, Inc.
Member since Sep 22, 2010
Location: San Francisco
In the examples for dynamic fragment manipulation, I used R.id.fragment_container to refer to the ID of some ViewGroup in the containing activity. I didn't actually show the activity layout in those examples so that I could focus more on the fragment-related code. In practice, you could use any type of ViewGroup (e.g., LinearLayout, RelativeLayout, FrameLayout, etc.) as the fragment container and assign it any ID resource that you like.
Posted on Sep 21, 2012
Photo Bhanu P
Student
Member since Sep 21, 2012
Can you give some more example on the uses of fragment?
Posted on Nov 5, 2012
Photo Nat Partouche
Dev Android
ECE
Member since Nov 5, 2012
Hi,
I am very poor as an android developer, I keep on learning using tutorials and Android documentation.
I am stock at a certain point :
I am working with Fragment basic sample from android.
I want to integrate an navigation in my global tab.
For that I need to understand well the behaviour of translation with Fragment on android!

This tutorial seems to be interesting for me, could you please add the source code of this tutorial in order to understand how it works.

I read this few time, but the right way to implement the navigation in the tab doesn't come up to me!!!

Thanks for you help! :)

Nat
Posted on Dec 20, 2012
Photo Nei Munhoz
Particular
Member since Dec 20, 2012
Hi, i've created two fragments with this code:
Code:

LinearLayout layout = new LinearLayout(this);
LinearLayout.LayoutParams lp0=new LinearLayout.LayoutParams(
ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT);

layout.setOrientation(LinearLayout.VERTICAL);
layout.setLayoutParams(lp0);layout.setBackgroundColor(Color.LTGRAY);
LinearLayout innerLayout1 =new LinearLayout(this);
innerLayout1.setOrientation(LinearLayout.HORIZONTAL);
LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(
ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
lp.weight = 0;
innerLayout1.setLayoutParams(lp);
innerLayout1.setId(R.id.fragcont);
innerLayout1.setBackgroundColor(Color.LTGRAY);
tb=new toolbar();
{
fragmentTransactiontb = getSupportFragmentManager().beginTransaction();
fragmentTransactiontb.add(R.id.fragcont,tb ,"toolbar");//fragmentTransactiontb.attach(tb );
fragmentTransactiontb.commit();
}
layout.addView(innerLayout1);

FrameLayout innerLayout2 = new FrameLayout(this);
FrameLayout.LayoutParams lp1 = new FrameLayout.LayoutParams(
ViewGroup.LayoutParams.MATCH_PARENT,metrics.heightPixels);

innerLayout2.setLayoutParams(lp1);
innerLayout2.setId(ITEM_DETAILS_ID);
{
FragmentTransaction fragmentTransaction = getSupportFragmentManager()
.beginTransaction();
fragmentTransaction.add(ITEM_DETAILS_ID, new camerafrag());
fragmentTransaction.commit();
}
layout.addView(innerLayout2);
setContentView(layout);

but when i try hide the first fragment nothing happens with this code:
Code:

FragmentManager fragmentManager = getSupportFragmentManager();
Fragment fr=fragmentManager.findFragmentByTag("toolbar");
fragmentManager.beginTransaction()
.hide(fr)
.commit();

what's wrong?

Regards
Nei Munhoz
Posted on Dec 20, 2012
Photo Ken Jones
Marakana, Inc.
Member since Sep 22, 2010
Location: San Francisco
Difficult for me to say for sure, but I did notice that you're assigning an ID to innerLayout1 programmatically, but the ID you're using is R.id.fragcont. As the R class is auto-generated by the build tools based on your application's resources, I'm concerned that R.id.fragcont might be associated with another View in your layout. This could cause confusion when you attempt to add the toolbar fragment and/or when you later find it programmatically. I'd suggest selecting a different ID set in your code, like you did with ITEM_DETAILS_ID.

You can use the Hierarchy Viewer tool to verify that your fragments are getting attached to the proper parent ViewGroups. If you've not used the tool before, you can find out more information about it at http://developer.android.com/tools/debugging/debugging-ui.html.

As for the code you use to hide the fragment, that looks correct. I suppose you could run your code in the debugger or add some logging code after the findFragmentByTag() to verify that you've found the correct fragment. But other than that, I can't think of what might cause the hide() method to fail to hide the fragment.
Posted on Jan 3, 2013
Photo Owen Thompson
Director/Engineer
Vitafit Software Limited
Member since Jan 3, 2013
Great tutorial Ken for the uninitiated. I am pleased at the way you have stated certain rules and best practices that must be applied when working with fragments. It would be nice if you can further expand on ListFragments sometime in the near future. Keep up the good work.
Posted on Jul 11, 2013
Photo Basanta Kumar
Software Developer
mPortal
Member since Jul 11, 2013
Very nice tutorial for beginners.I am very happy the way it explained.It will be good if you give some example for communicating fragment with activity and how to pass data from one fragment to another fragment.
Posted on Oct 29, 2013
Photo Find Me
Micrrosoft
Member since Oct 29, 2013
Hello ......... Excellent tutorial
.
Can you post a similar tutorial for a regular Activity Life Cycle
.
Android Developer Docs are not this precise
.
Thanks
Posted on Jan 21, 2014
Photo Zafer Celaloglu
Bahcesehir University
Member since Jan 21, 2014
Hi all,

I think this tutorial is informative but so complicated so you can put all of the codes to the github ,we can check and dowland into our pc to test in oder to understand completely.

Thanks for tutorial