Smartphones

Get started with Android fragments

After purchasing and using a Sony Tablet S, William J. Francis is sold on the idea of Android fragments. His tutorial shows how to create a functional fragment-based UI.

I like learning new things, but I'm not someone who stops and refactors every app I've ever built just because a new design pattern, widget, or paradigm is announced. I appreciate tried and true, and while I try to keep my eyes open and an ear to the ground, I prefer a compelling reason to add a new hammer to my digital toolbox.

This way of doing things has put me on the fence about Android fragments for a while. I attended a couple workshops on the subject, read a number of good blog posts about fragments (including one by my fellow TechRepublic blogger Kyle Miller), and learned there is a compatibility API, and yet I've been slow to jump on the fragments train.

Then a few weeks ago, I purchased and began using a Sony Tablet S. In a matter of days, I began to see the appeal of fragments. In fact, without making any conscious decision to do so, I found myself avoiding those apps that didn't support the intuitive fragment-based layouts. For the record, that includes all of the apps I've coded and released to the market up to this point.

That realization hit me like a tons of bricks. I pulled out the old laptop, rolled up my sleeves, and began exploring fragments in earnest. What I quickly found was that the simplicity fragments add to the end user experience comes at the price of complexity for the developer. That's okay. At the end of the day the effort that goes into making an app doesn't matter unless someone wants to use the finished product. I _think_ I'm getting my head around the key fragment implementation concepts. More importantly, I'm sold on the idea of fragments going forward.

The following tutorial is a stripped down fragment-based interface. If you've been thinking about giving the fragment API a try in your apps, this tutorial is for you. You can follow along or download the project and import it directly into Eclipse.

1. Create a new Android project using Eclipse. To natively support fragments, you must target Android 3.0 (Honeycomb) or greater. Be sure to change the name of the startup activity to Main.java.

2. For the demo, we will use two layouts: One to represent our main container which holds the two fragments, and a second one to define our detail fragment. The list fragment we will define in code by extending the handy ListFragment class. Add the following layouts to your /res/layout folder.

main.xml

<?xml version="1.0" encoding="utf-8"?>

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"

android:layout_width="fill_parent"

android:layout_height="fill_parent"

android:orientation="horizontal" >

<fragment

android:id="@+id/frag_series"

android:layout_width="200dip"

android:layout_height="match_parent"

android:layout_marginTop="?android:attr/actionBarSize"

class="com.authorwjf.hello_fragments.ListFrag" />

<fragment

android:id="@+id/frag_capt"

android:layout_width="match_parent"

android:layout_height="match_parent"

class="com.authorwjf.hello_fragments.DetailFrag" />

</LinearLayout>

detail_fragment.xml

<?xml version="1.0" encoding="utf-8"?>

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"

android:layout_width="match_parent"

android:layout_height="match_parent"

android:orientation="vertical" >

<TextView

android:id="@+id/captain"

android:layout_width="wrap_content"

android:layout_height="match_parent"

android:layout_gravity="center_horizontal|center_vertical"

android:layout_marginTop="20dip"

android:text="Johnathan Archer"

android:textAppearance="?android:attr/textAppearanceLarge"

android:textSize="30dip" />

</LinearLayout>

3. We are ready to move on to the source folder. Because fragments act almost like activities, the code in Main.java does nothing more than load the topmost layout.

Main.java
package com.authorwjf.hello_fragments;
import android.app.Activity;
import android.os.Bundle;
public class Main extends Activity {

@Override

public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState);

setContentView(R.layout.main);

}

}

4. Our DetailFrag.java implementation is nearly as simple; it inflates a view and exposes a setText method.

DetailFrag.java
package com.authorwjf.hello_fragments;
import android.app.Fragment;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
public class DetailFrag extends Fragment{

@Override

public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState);

}

@Override

public void onActivityCreated(Bundle savedInstanceState) { super.onActivityCreated(savedInstanceState);

}

@Override

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

}

public void setText(String item) {

TextView view = (TextView) getView().findViewById(R.id.captain);

view.setText(item);

}

}

5. Last is the ListFrag.java file. We create a list view, implement the on click, and make use of the fragment manager to reference one fragment from another. In the onListItemClick() method, notice the check for whether the target fragment exists in this particular layout -- that allows a developer to implement a separate layout for smaller screen devices like phones. Perhaps if this post generates enough interest I will go back and extend this tutorial to do just that.

ListFrag.java
package com.authorwjf.hello_fragments;
import android.app.ListFragment;
import android.os.Bundle;
import android.view.View;
import android.widget.ArrayAdapter;
import android.widget.ListView;
public class ListFrag extends ListFragment{

@Override

public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState);

}

@Override

public void onActivityCreated(Bundle savedInstanceState) { super.onActivityCreated(savedInstanceState); String[] values = new String[] { "Enterprise", "Star Trek", "Next Generation", "Deep Space 9", "Voyager"}; ArrayAdapter<String> adapter = new ArrayAdapter<String>(getActivity(), android.R.layout.simple_list_item_1, values);

setListAdapter(adapter);

}

@Override

public void onListItemClick(ListView l, View v, int position, long id) {

String item = (String) getListAdapter().getItem(position);

DetailFrag frag = (DetailFrag) getFragmentManager().findFragmentById(R.id.frag_capt);

if (frag != null && frag.isInLayout()) {

frag.setText(getCapt(item));

}

}

private String getCapt(String ship) { if (ship.toLowerCase().contains("enterprise")) { return "Johnathan Archer";

}

if (ship.toLowerCase().contains("star trek")) { return "James T. Kirk";

}

if (ship.toLowerCase().contains("next generation")) { return "Jean-Luc Picard";

}

if (ship.toLowerCase().contains("deep space 9")) { return "Benjamin Sisko";

}

if (ship.toLowerCase().contains("voyager")) { return "Kathryn Janeway";

}

return "???";

}

}

We are ready to execute the demo. If you own an Android tablet, go ahead and download the APK to the device. If not, you can easily simulate a tablet using the ADB plugin for Eclipse and the Android Virtual Device Manager by following these steps:

1. Create an emulated device running Android API level 11.

2. Set the skin to 1280x800 pixels.

3. Bump up the device ram to 1024.

4. Set the LCD density to 149.

This should give you roughly the same experience as a first generation Motorola Xoom device.

There you have it -- a rudimentary but functional fragment-based UI. The more I dig into the API, the greater appreciation I'm gaining for both the flexibility and power of fragments.

Figure A

Figure B

If you have thoughts about or experiences with Android fragments, share them with the TechRepublic community. We'd love to hear from you.

About

William J Francis began programming computers at age eleven. Specializing in embedded and mobile platforms, he has more than 20 years of professional software engineering under his belt, including a four year stint in the US Army's Military Intellige...

7 comments
InnPe
InnPe

Maybe you know, why any Projekt with Fragments does not start in Eclipse? Always the same: The Application  has stopped unexpectedly. Please try again. 

Aexyno
Aexyno

You know you wrote a great article if someone joins your site just to thank you.. simple to the point article that works without any complications.. great for beginners

moberme
moberme

Thank you for a tutorial that did not drag on for pages and pages of code. This is really clear and to the point

bart_nada
bart_nada

I have a question, in the androidManifest.xml exists the declaration : activity android:name=".DetailActivity" activity But i don't understand how worked, not exist any activity with this name. How worked this? Thanks Again.

bart_nada
bart_nada

I have a question, in the androidManifest.xml exists the declaration : activity android:name=".DetailActivity" > /activity But i don't understand how worked, not exist any activity with this name. How worked this? Thanks Again.

blakjak.au
blakjak.au

"I pulled out the old laptop, rolled up my sleeves, and began exploring fragments in earnest." I know it doesn't appeal to everyone, but with a decent Bluetooth keyboard (or in my case a Transformer Prime) you can develop for android directly on your device using AIDE (no affiliation to me) which lets you code, complie and run your apps directly on your device - be it a tablet or phone. I discovered this app recently and now I don't touch my laptop for android development.

Editor's Picks