What are Android fragments?

I had a post a while back where I talked about the differences and similarities between Apple apps and Android apps. In that post I explained that Apple uses a model/view/control (MVC) architecture for constructing their apps, where Google defines activities and intents. What this means is that on Apple devices, the user interface is contained in a series of ViewControllers that are displayed on a story board and liked by different types of transitions. On Android devices the UI is contained in an Activity and defined in an XML file called a layout. Each layout typically contains a single UI page and transitions are handled by sending an “intent” to the underlying OS.

One very cool side effect of the Android model is that any application on you device can be launched by any other application by simply passing its intent to the operating system. An example of this would be a bar code scanner. If you want to scan a bar code from inside your application you can create an intent to launch the bar code scanner and describe a call back that will deliver the result to your application. In this case you didn’t have to write the scanner yourself, but it does have to be installed on the system.

Static UI pages worked well initially, but as applications increased in complexity, users wanted segmented UI’s that contained a collection of smaller UI’s. On an Android device, Fragments are similar to activities. They have a life cycle like activities, but they represent re-usable parts of an android user interface (UI). You can combine fragments to make a robust and flexible user interface that can be adjusted depending on the target device. You can dynamically change fragments to modify the content displayed depending on user input.

The base class of all fragments is “Fragment” and although there is a backwards compatibility package, Fragments are really only supported in android version 3.0 or later. For those of you who know releases only by their names, that would be ice cream sandwich and jellybean.

Fragments, like activities, each have their own layout which is defined in an XML file and located in the layouts folder of the application. There can be different layouts for landscape and portrait modes. A fragment must always be embedded in an activity and the fragment’s life cycle is directly affected by the host activity’s life cycle. When you add a fragment as a part of your activity layout, it lives in a “ViewGroup” inside the activity’s view hierarchy and the fragment defines its own view layout.

The diagram above shows how fragments can be combined on devices with a large amount of real estate and separated on devices with smaller screens. The advantage here is that the fragment itself does not change.

Because a fragment is usually used as part of an activity’s user interface and contributes its own layout to the activity.

To provide a layout for a fragment, you must implement the “onCreateView” callback method, which the Android system calls when it’s time for the fragment to draw its layout. Your implementation of this method must return a “View” that is the root of your fragment’s layout.

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

The code above shows a sample implementation of a fragment. Note that you have to use an inflater to tell the fragment to lay itself out.

To add a fragment to an Activity you can statically define the fragment in the Activitie’s XML layout file, or dynamically add it via the activities supporting Java code.

<?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>

This first example shows two statically define fragments.

FragmentManager fragmentManager = getFragmentManager()
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
ExampleFragment fragment = new ExampleFragment();
fragmentTransaction.add(R.id.fragment_container, fragment);
fragmentTransaction.commit();

The example above shows fragments being added at run time.

Fragments are a cool way to define re-usable UI components that can be moved from project to project as well as between different layouts.

This entry was posted in General and tagged , , , , . Bookmark the permalink.

Leave a Reply

Your email address will not be published. Required fields are marked *