A Brief Overview of Android Fragments

By Sean Kollipara

Introduction: Activities

When learning to develop for the Android platform, one of the first components of the Android SDK that you will encounter is the Activity object.  An activity is the basic component that provides UI and functionality in an Android app.  It has a lifecycle and callbacks associated with the lifecycle events, and is contained within its own window.  Multiple activities are usually present in a single application.

For example, consider Cogent’s directory app, mPower mD.  When launching mD, the first thing you see is the login screen.  It is its own activity.  Upon successful login, the login activity closes, and the home activity appears.  The home activity contains tabs that enable the user to navigate through the app content.  This is the basic gist of an activity.

Meet Fragments

Android 3.0 introduced the concept of a fragment.  A fragment can be thought of as a reusable piece of an activity.  It can have either or both of its own UI and functionality.  Like an activity, a fragment has its own lifecycle and set of callbacks to response to its lifecycle events.  Creating a fragment is easy: make a new class that extends the Fragment class.

public class MyFragment extends Fragment {

 …

}

Fragment Lifecycle Callbacks

When creating your own fragment, there are a couple of lifecycle callbacks you’ll want to define at minimum.  The first is onCreate().  It is just like the method of the same name in an activity.  It takes a bundle parameter and you use it to perform initialization activities, such as a call to the superclass.

@Override

public void onCreate(Bundle savedInstanceState) {

  super.onCreate(savedInstanceState);

  …

}

Unlike an activity, a fragment does not have a setContentView() method.  Instead, it has a lifecycle callback named onCreateView().  This is the other callback that you’ll probably want to define.  This callback is used to inflate a view and perform other operations on it as necessary.  For example, you might want to assign some of the UI elements as members of the class if you need to perform operations on them during the fragment’s lifecycle.

class MyFragment extends Fragment {

  public Button mButton;

 @Override

     public void onCreate(Bundle savedInstanceState) {

    super.onCreate(savedInstanceState);

    …

  }

  @Override

  public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {

    View myView = inflater.inflate(R.layout.myview, container, false);

    mButton = (Button) v.findViewById(R.id.mybutton);

    return myView;

  }

}

Other lifecycle callbacks for fragments include onAttach(), onActivityCreated(), onStart(), onResume(), onPause(), onStop(), onDestroyView(), onDestroy(), and onDetach().  As you can see, many of these are similar to the lifecycle callbacks for an activity, though a few are specific to fragments only.

Why use fragments instead of activities?

Fragments are an ideal solution when you need reusable pieces of UI and function that go together.  For instance, you might have an app where the phone layout has the main content in the entire screen and the menu in a navigation drawer.  But, in order to make use of increased screen real estate, your tablet layout has the content on the screen with the menu as a sidebar on the left.  The menu, with its UI and own functionality, is a reusable component that can be utilized in both layouts.  The same is true for the content.  Thus, it is sensible to put each of these two pieces in its own fragment.

Why not create and swap views or view groups instead?

This is a good question because it suggests a viable alternative to using fragments.  The main reason you would pick fragments over views and view groups is because they have a lifecycle and a backstack.  If either of these features are needed, it is advisable to use the fragment.  Otherwise, you’d have to roll your own lifecycle or backstack, and that would end up being a project in and of itself.  So the best course of action would be to use a fragment.

Special Types of Fragments

There are a few special types of fragments available for common UI paradigms.  In mobile apps, there are often master-detail design flows, where the master component is a list.  For this purpose, the Android SDK provides a special type of fragment called a ListFragment.  It inherits from Fragment and contains a ListView with the ID @android:id/list.  It can also be subclassed and customized to your liking, provided that the view contains a ListView element with the aforementioned ID.  For more information, see the Android development documentation for ListFragment.

Another special type of fragment is the PreferenceFragment.  This replaces the deprecated PreferenceActivity with a fragment that is wrapped by a FragmentActivity.  The PreferenceFragment can be used in a manner just like the PreferenceActivity in order to load an XML definition of preferences into the UI so that the user can customize the app to their liking.

The Fragment Manager and Fragment Transactions

Android contains a special Activity called a FragmentActivity, which includes an object called a FragmentManager.  The fragment manager allows the developer to manage the fragments that appear in each of the fragment containers defined in a view.  The fragments are loaded, switched, and removed through the use of transactions.

Within the FragmentActivity, you can start a FragmentTransaction by grabbing the fragment manager and calling the beginTransaction() method:

FragmentTransaction txn = getFragmentManager().beginTransaction();

Note: if you are using ActionBarSherlock, you should use getSupportFragmentManager() instead.

Once you have a handle for a fragment transaction, you can call various functions to add, switch, hide, show, and remove fragments:

Fragment myFragment = new MyFragment();

Fragment myOtherFragment = new MyOtherFragment();

txn.add(R.id.my_fragment_container, myFragment, “my_fragment”);

txn.replace(R.id.my_fragment_container, myOtherFragment);

txn.remove(myFragment);

Finally, to complete the transaction, call the commit() method:

txn.commit();

For a full rundown of the available methods in the fragment manager, see the FragmentTransaction documentation on the Android developer website.

Conclusion

Fragments are a bit confusing at first, but with some time spent researching and playing with code, it becomes easy to understand how they work.  Once you begin to incorporate them into your app, you can see the benefits of performance and reusability that they can bring to your Android app development.  For those who are new to fragments, I hope this post has helped to introduce you to the concept and provide a basic level of understanding as to their function and benefit.  Feel free to leave comments, suggestions, and questions in the comments section.

Happy coding!

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s