Get $500+ of the best After Effects files, video templates and music for only $20!
Android User Interface Design: Building a ListView Application

Android User Interface Design: Building a ListView Application

Tutorial Details
  • Technology: Eclipse + Android SDK
  • Difficulty: Intermediate
  • Estimated Completion Time: 60-90 Minutes
This entry is part 9 of 21 in the series Android User Interface Design

The ListView is one of the most useful view controls available on the Android platform for the display of variable amounts of data. In this Mobiletuts+ tutorial, we’ll show you how to use a ListView to browse a list of articles!

Over the last several months, you’ve seen many tutorials covering various layout controls. You’ll use several of these in conjunction with a ListView in today’s tutorial. The application itself will be very simple: it will display a list of article titles which, when clicked, display the article’s content. The pacing of this tutorial is going to be faster than some of our beginning tutorials; you may have to review some of our other tutorials on this site or even in the Android API reference if you are unfamiliar with basic Android controls or concepts. The final open-source code is available for download on Google code hosting.

Step 0: Creating a Project

Create a new Android project in Eclipse. We’ve named ours MT-List, with a starting activity named TutListActivity. This Activity must extend the ListActivity class, which is a special Activity class that helps manage a ListView control. We’re using a target API Level of 10 (Android 2.3.3).

Step 1: Designing the List Screen

Actually, there is very little design work here. A ListView control consists of repeating items, each with the same layout (a template for an item). We want to display a list of article titles. Each title will be a single item in the ListView. Therefore, the template for each list item need only have a TextView control. Add a new layout resource file to your project named list_item.xml which represents the template layout for each item in the list. In this case, it should look like this:

<?xml version="1.0" encoding="utf-8"?>
<TextView
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:textSize="24dp"
    android:padding="6dp" />

The text size plus the padding attributes ensure that each list item is a big enough touch target for the average human finger on an average sized screen..

Step 2: Populating the ListView with Data

ListView controls are design to load data from a data source. An adapter can be used to read from a database, array, or other data source. We’ll use an array implementation for this application. Later on, you could always replace the array with some sort of live data source. Create two string-array resources in your project (you can add them to strings.xml or a separate arrays.xml file, your choice). Name one array “tut_titles” and the other “tut_links”. Fill in the arrays with valid titles and valid URLs from the Mobiletuts+ website. Here are our arrays:

<string-array name="tut_titles">
    <item>Design &amp; Build a 1980s iOS Phone App: Design Comp Slicing</item>
    <item>Best of Tuts+ in February 2011</item>
    <item>Create a Brick Breaker Game with the Corona SDK: Game Controls</item>
    <item>Exporting Graphics for Mobile Apps: PNG or JPEG?</item>
    <item>Android Tablet Design</item>
    <item>Build a Titanium Mobile Pizza Ordering App: Order Form Setup</item>
    <item>Create a Brick Breaker Game with the Corona SDK: Application Setup</item>
    <item>Android Tablet Virtual Device Configurations</item>
    <item>Build a Titanium Mobile Pizza Ordering App: Topping Selection</item>
    <item>Design &amp; Build a 1980s iOS Phone App: Interface Builder Setup</item>
</string-array>
<string-array name="tut_links">
    <item>http://mobile.tutsplus.com/tutorials/mobile-design-tutorials/80s-phone-app-slicing/</item>
    <item>http://mobile.tutsplus.com/articles/news/best-of-tuts-in-february-2011/</item>
    <item>http://mobile.tutsplus.com/tutorials/corona/create-a-brick-breaker-game-with-the-corona-sdk-game-controls/</item>
    <item>http://mobile.tutsplus.com/tutorials/mobile-design-tutorials/mobile-design_png-or-jpg/</item>
    <item>http://mobile.tutsplus.com/tutorials/android/android-tablet-design/</item>
    <item>http://mobile.tutsplus.com/tutorials/appcelerator/build-a-titanium-mobile-pizza-ordering-app-order-form-setup/</item>
    <item>http://mobile.tutsplus.com/tutorials/corona/corona-sdk_brick-breaker/</item>
    <item>http://mobile.tutsplus.com/tutorials/android/android-sdk_tablet_virtual-device-configuration/</item>
    <item>http://mobile.tutsplus.com/tutorials/appcelerator/pizza-ordering-app-part-2/</item>
    <item>http://mobile.tutsplus.com/tutorials/iphone/1980s-phone-app_interface-builder-setup/</item>
</string-array>

This data is, of course, static. In some cases, using static data can make sense for a ListView. Using a string array resource for these cases turns out to be very easy and convenient. Just make sure the ordering of the titles and their links is identical, such that the array indices match.

Step 3: Adapting the Data to the ListView

Now that the application has data, it’s time to display it. Back in TutListActivity.java, modify the onCreate() method to use the setListAdapter() method to load up the data. Unlike regular activities, a ListActivity does not need the use of setContentView() for cases where the entire activity is just a ListView. When done, your entire ListActivity will now look like this:

public class TutListActivity extends ListActivity {
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        setListAdapter(ArrayAdapter.createFromResource(getApplicationContext(),
                R.array.tut_titles, R.layout.list_item));
    }
}

At this point, you can run the application. You’ll now see a ListView with all of the titles of the tutorials. Scrolling up and down works as expected. However, clicking a title does not do anything yet.

Android Listview Figure 1

Step 4: Handling ListView Item Clicks

Handling clicks on items within a ListView is done in a similar way to other View objects: by using a listener. In this case, we’re interested in the OnTimeClickListener. You might have noticed that we haven’t once dealt with the ListView object directly. Now is the time. In a ListActivity, simply make a call to the getListView() method to retrieve the ListView and then call the setOnItemClickListener() method and implement it all in one go:

getListView().setOnItemClickListener(new OnItemClickListener() {

    @Override
    public void onItemClick(AdapterView<?> parent, View view,
            int position, long id) {
        // TBD
    }
});

The onItemClick() method will be called each time the user clicks on a particular item within the ListView. Conveniently, it passes in several useful parameters, one of which we’ll need for launching the viewer activity. Wait, what viewer activity?

Step 5: Creating the Viewer Activity

Good question. Let’s create a viewer activity now! This activity will be used to display the tutorial contents to the user. Create a new class by extending Activity and name it TutViewerActivity.java. Create a layout resource file for it that has exactly one item: a WebView control. The layout file should look like this:

<?xml version="1.0" encoding="utf-8"?>
<WebView
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:id="@+id/tutView">
</WebView>

Within the onCreate() method of the TutViewerActivity class, call the setContentView() method and pass in this layout. Finally, don’t forget to add the activity to your AndroidManifest.xml file.

Step 6: Launching the Details Activity

Switch your attention back to TutListActivity for a moment. Let’s look at what we need to do to launch the viewer Activity with the appropriate article link. Inside the onItemClick() method, the position of the item that was clicked is passed in as an int type value. This is exactly what we need for accessing the array of article links.

The string values within the links array are URLs. A convenient way to pass a URL to another activity is by adding a Uri to the Intent via the setData() method. Here is the final onItemClick() implementation which starts the viewer activity, passing in the appropriate URL:

@Override
public void onItemClick(AdapterView<?> parent, View view,
        int position, long id) {
    String content = links[position];
    Intent showContent = new Intent(getApplicationContext(),
            TutViewerActivity.class);
    showContent.setData(Uri.parse(content));
    startActivity(showContent);
}

If you just paste that at the end of the onCreate() method, you’ll notice that the links variable isn’t defined yet. Since it’ll be used within the OnItemClickListener class, the variable must be a final value, like so:

final String[] links = getResources().getStringArray(R.array.tut_links);

This line must be placed before the OnItemClickListener definition. Yes, you could have made it a member variable without being final. For a more complex case, that might even be necessary. But, in this case, we can actually keep all code within the method.

At this point, if you run the application, you’ll get a blank white viewer screen. The activity is launched correctly, but we need to go wire up the viewer activity to load the URL in the WebView control.

Step 7: Loading the URL

Turn your attention back to TutViewerActivity.java. After the setContentView() call, add code to retrieve the Uri from the passed in Intent and convert it to a String variable. Then add a call to the loadUrl() method of the WebView class. The entire TutViewerActivity class will now look like this:

public class TutViewerActivity extends Activity {
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.tut_view);

        Intent launchingIntent = getIntent();
        String content = launchingIntent.getData().toString();

        WebView viewer = (WebView) findViewById(R.id.tutView);
        viewer.loadUrl(content);
    }
}

Run the application now. Does it work? Not quite yet! One final detail: you need to add the Internet permission to the AndroidManifest.xml file. Now run the application. You’ll now see that the implementation works:

Android Listview Figure 2

Step 8: Refining the Experience (Optional)

The experience, as-is, works. A ListView shows all of the article titles, a user can click on a specific list item and be redirected to an activity with a WebView to show the appropriate URL. Some refinements that you might consider making to this basic implementation include:

  • Setting the initial zoom of the browser view to be zoomed out further
  • Configuring the WebView to have more control over the browsing experience
  • Loading the list of tutorials dynamically, instead of via a static array
  • Adding fancy visual attributes to the ListView
  • Making better use of larger screens (i.e. fragments)
  • Adding supplementary information to the ListView items: subtitles, difficulty levels, icons, “read” indicators, favorites, etc.

Other Android tutorials on this site will teach you how to perform many of these optional features. Others you may have to discover yourself — or ask about in the comments!

Conclusion

The ListView widget is a fast way to organize data in a list format on the screen. We have only scratched the surface of the ListView control in this tutorial. However, you have learned the basics of: creating list items, working with data adapters, and handling list item clicks.

About the Authors

Mobile developers Lauren Darcey and Shane Conder have coauthored several books on Android development: an in-depth programming book entitled Android Wireless Application Development and Sams Teach Yourself Android Application Development in 24 Hours. When not writing, they spend their time developing mobile software at their company and providing consulting services. They can be reached at via email to androidwirelessdev+mt@gmail.com, via their blog at androidbook.blogspot.com, and on Twitter @androidwireless.

Need More Help Writing Android Apps? Check out our Latest Books and Resources!

Buy Android Wireless Application Development, 2nd Edition  Buy Sam's Teach Yourself Android Application Development in 24 Hours  Mamlambo code at Code Canyon

Series Navigation«Android User Interface Design: Frame LayoutsAndroid User Interface Design: Working With Fragments»

Add Comment

Discussion 26 Comments

  1. Android says:

    Nice example, to get through with the listview, like this if we need to check with custom listview of need to go through with multiple listview in a activity means we can go with this link http://android-codes-examples.blogspot.com/2011/03/multiple-listview-and-custom-listview.html

  2. Chaos says:

    Setting up the tut_view.xml is never covered. Searching the page reveals that the first time tut_view is mentioned is inline with the setContentView(R.layout.tut_view).

    Could you update the tutorial to illustrate how tut_view.xml should look?

    Thanks. Great tutorial, otherwise. Trying to do this and move onto the Fragments.

    • Chaos says:

      Nevermind…there is a difference between layout and id, isn’t there?

      Yeah. Great tutorial…get the pupil thinking and not just doing.

  3. Himo says:

    Design a mobile application which will have a main ListView interface ( for the main activity of the app) with 3 items which when selecting the item with a given index will:
    0) give the user an option to give some integer numbers ( for end let the user enter -1) by an edittext box and store those in an array, then one button Max which on click will then find the maximum of those numbers stored in the array and show the result within a textbox.
    1) give the user an option to give some integer numbers ( for end let the user enter -1) by an edittext box and store those in an array, then one button Min which on click will then find the minimum of those numbers stored in the array and show the result within a textbox.
    Note here, you have to define your own adapter which will show different icon on the list item ( for max).

    CAN ANYONE HELP ME WITH THESE

  4. fennou says:

    i have followed the same steps as you but , it dosen’t work :( the emulatore displays this message ” the application NAME_OF_APPLICATION ( process PACKAGE ) has stopped unexpectedly . please try again “

  5. Developers says:

    Gr8 Tuts…Thanks for sharing

  6. Typo on step 4 – “OnTimeClickListener”

  7. sathya says:

    Thanks ..

    Nice tutorial.. helped a lot

  8. Max says:

    I was having issue on step #6 with the StartActivity method failing and found this link:
    http://androidforums.com/application-development/103343-startactivity-crashing.html

    Thanks to markb; if you have this problem, my missing link was the Activity reference in the AndroidManifest.xml file:

    I added the test_viewer string as well in res/values/strings.xml:
    UITestViewer

    Thank you Shane and Lauren; this was a great and very relevant tutorial.

    • Martin says:

      Because I’m a total Android noob, it’d took a little work (which is good) to figure out what the missing link was… For those who are noobish, here is the what was missing:

      I placed it immediately following the line (belongs to <activity android:name=".TutListActivity").

      HTH

  9. Maxim says:

    I created a listview application and everything works fine, the problem is, that I can’t figure out how to keep the selected state of the item I click on: In other words when I press on it it turns orange, displays the list item, and the orange goes away, how do I make stay orange?

    Thanks,
    I hope you understand my explanation

  10. Guest says:

    > setListAdapter(ArrayAdapter.createFromResource(getApplicationContext(),
    > R.array.tut_titles, R.layout.list_item));

    Ugh.

    Nothing can work without that list_item you forgot to include.

  11. Judes says:

    good one to beginners

  12. gamini says:

    Hi

    Education complex

    I work step by step, but did not succeeded

    3 Days In the implementation of the project but does not benefit

    We want the names all files

    For example
    list_item.xml & tutView & a what

    Note: main.xml & strings.xml “I did not work out anything”

    “Could you update the tutorial to illustrate”

    =======================================================
    Look at this :

    TutListActivity.java

    import android.app.ListActivity;
    import android.content.Intent;
    import android.net.Uri;
    import android.os.Bundle;
    import android.view.View;
    import android.widget.AdapterView;
    import android.widget.AdapterView.OnItemClickListener;
    import android.widget.ArrayAdapter;

    public class TutListActivity extends ListActivity {

    final String[] links = getResources().getStringArray(R.array.tut_links);
    @Override
    public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setListAdapter(ArrayAdapter.createFromResource(getApplicationContext(),
    R.array.tut_titles, R.layout.list_item));

    getListView().setOnItemClickListener(new OnItemClickListener() {

    public void onItemClick(AdapterView parent, View view,
    int position, long id){
    String content = links[position];
    Intent showContent = new Intent(getApplicationContext(),
    TutViewerActivity.class);
    showContent.setData(Uri.parse(content));
    startActivity(showContent);

    }});

    }};
    =======================================================

    TutViewerActivity.java

    import android.app.Activity;
    import android.content.Intent;
    import android.os.Bundle;
    import android.webkit.WebView;

    public class TutViewerActivity extends Activity {
    @Override
    public void onCreate(Bundle savedInstanceState){
    super.onCreate(savedInstanceState);
    setContentView(R.layout.tut_view);

    Intent launchingIntent = getIntent();
    String content = launchingIntent.getData().toString();

    WebView viewer = (WebView) findViewById(R.id.tutView);
    viewer.loadUrl(content);
    }

    }
    ========================================================

    list_item.xml

    ======================================================

    tut_view.xml

    ===================================================

    arrays.xml

    Design & Build a 1980s iOS Phone App: Design Comp Slicing
    Best of Tuts+ in February 2011
    Create a Brick Breaker Game with the Corona SDK: Game Controls
    Exporting Graphics for Mobile Apps: PNG or JPEG?
    Android Tablet Design
    Build a Titanium Mobile Pizza Ordering App: Order Form Setup
    Create a Brick Breaker Game with the Corona SDK: Application Setup
    Android Tablet Virtual Device Configurations
    Build a Titanium Mobile Pizza Ordering App: Topping Selection
    Design & Build a 1980s iOS Phone App: Interface Builder Setup

    http://mobile.tutsplus.com/tutorials/mobile-design-tutorials/80s-phone-app-slicing/
    http://mobile.tutsplus.com/articles/news/best-of-tuts-in-february-2011/
    http://mobile.tutsplus.com/tutorials/corona/create-a-brick-breaker-game-with-the-corona-sdk-game-controls/
    http://mobile.tutsplus.com/tutorials/mobile-design-tutorials/mobile-design_png-or-jpg/
    http://mobile.tutsplus.com/tutorials/android/android-tablet-design/
    http://mobile.tutsplus.com/tutorials/appcelerator/build-a-titanium-mobile-pizza-ordering-app-order-form-setup/
    http://mobile.tutsplus.com/tutorials/corona/corona-sdk_brick-breaker/
    http://mobile.tutsplus.com/tutorials/android/android-sdk_tablet_virtual-device-configuration/
    http://mobile.tutsplus.com/tutorials/appcelerator/pizza-ordering-app-part-2/
    http://mobile.tutsplus.com/tutorials/iphone/1980s-phone-app_interface-builder-setup/

    ================================================================

    Thank you very much…

  13. Mahmoud says:

    The application is crashed, didn’t know why?

  14. James says:

    How to add a header or footer of the list? Thanks!

  15. Martin says:

    where do you paste step #4 not very detailed on what to do with that piece of code.

  16. Edd says:

    Hi thanks for the great tutorials. My tutlistactivity and tutvieweractivity are the same as the code above. Im sure my layouts and resources are correct and same with arrays and strings. Compiles fine then when i try to load the application unexpectedly closes. Logcat says the following:

    04-10 18:29:28.066: W/dalvikvm(1469): threadid=1: thread exiting with uncaught exception (group=0×40015560)
    04-10 18:29:28.319: E/AndroidRuntime(1469): FATAL EXCEPTION: main
    04-10 18:29:28.319: E/AndroidRuntime(1469): java.lang.RuntimeException: Unable to instantiate activity ComponentInfo{com.bcs.test/com.bcs.test.TutListActivity}: java.lang.NullPointerException
    04-10 18:29:28.319: E/AndroidRuntime(1469): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1544)
    04-10 18:29:28.319: E/AndroidRuntime(1469): at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:1638)
    04-10 18:29:28.319: E/AndroidRuntime(1469): at android.app.ActivityThread.access$1500(ActivityThread.java:117)
    04-10 18:29:28.319: E/AndroidRuntime(1469): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:928)
    04-10 18:29:28.319: E/AndroidRuntime(1469): at android.os.Handler.dispatchMessage(Handler.java:99)
    04-10 18:29:28.319: E/AndroidRuntime(1469): at android.os.Looper.loop(Looper.java:123)
    04-10 18:29:28.319: E/AndroidRuntime(1469): at android.app.ActivityThread.main(ActivityThread.java:3647)
    04-10 18:29:28.319: E/AndroidRuntime(1469): at java.lang.reflect.Method.invokeNative(Native Method)
    04-10 18:29:28.319: E/AndroidRuntime(1469): at java.lang.reflect.Method.invoke(Method.java:507)
    04-10 18:29:28.319: E/AndroidRuntime(1469): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:839)
    04-10 18:29:28.319: E/AndroidRuntime(1469): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:597)
    04-10 18:29:28.319: E/AndroidRuntime(1469): at dalvik.system.NativeStart.main(Native Method)
    04-10 18:29:28.319: E/AndroidRuntime(1469): Caused by: java.lang.NullPointerException
    04-10 18:29:28.319: E/AndroidRuntime(1469): at android.content.ContextWrapper.getResources(ContextWrapper.java:80)
    04-10 18:29:28.319: E/AndroidRuntime(1469): at com.bcs.test.TutListActivity.(TutListActivity.java:15)
    04-10 18:29:28.319: E/AndroidRuntime(1469): at java.lang.Class.newInstanceImpl(Native Method)
    04-10 18:29:28.319: E/AndroidRuntime(1469): at java.lang.Class.newInstance(Class.java:1409)
    04-10 18:29:28.319: E/AndroidRuntime(1469): at android.app.Instrumentation.newActivity(Instrumentation.java:1021)
    04-10 18:29:28.319: E/AndroidRuntime(1469): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1536)
    04-10 18:29:28.319: E/AndroidRuntime(1469): … 11 more
    04-10 18:29:28.576: W/ActivityManager(60): Force finishing activity com.bcs.test/.TutListActivity
    04-10 18:29:29.226: W/ActivityManager(60): Activity pause timeout for HistoryRecord{4053f4b8 com.bcs.test/.TutListActivity}
    04-10 18:29:35.036: D/dalvikvm(135): GC_EXPLICIT freed 178K, 50% free 3030K/5959K, external 4943K/6062K, paused 52ms
    04-10 18:29:39.436: D/dalvikvm(242): GC_EXPLICIT freed 8K, 55% free 2597K/5703K, external 1625K/2137K, paused 255ms
    04-10 18:29:42.436: D/SntpClient(60): request time failed: java.net.SocketException: Address family not supported by protocol
    04-10 18:29:44.109: W/ActivityManager(60): Activity destroy timeout for HistoryRecord{4053f4b8 com.bcs.test/.TutListActivity}
    04-10 18:29:45.292: D/dalvikvm(312): GC_EXPLICIT freed 3K, 54% free 2537K/5511K, external 1625K/2137K, paused 647ms

    Believe it may be problem with my androidmanifest.xml

    Any help would be greatly appreciated.

    Thanks

Add a Comment

To add a code snippet to your comment, please wrap your code like so: <pre name="code" class="html">YOUR CODE</pre>. You can replace the class name with "js," "css," "sql," or "php." If there are any "<" or ">" within your code, please search and replace them with: &lt; and &gt; respectively.