Lists and Adapters in Android

Coming from iOS development, I knew that learning to display large data sets would be crucial to building powerful mobile applications.

Android’s ListView is essentially the iOS equaivalent of UITableView. In iOS, we use the data-source and delegate design patterns to map data, as well as respond, to our table-views.

Lists in Android are not much different; they abide by MVC design, and once you get the pattern down it is a consistent and straight forward process.

Step 1: Extend ListActivity from your Activity

public class DailyForecastActivity extends ListActivity {

Step 2: Add a ListView to the activity (with “list” as its id)

An important detail here is that the id of your ListView must be “list” in order to be used propery with ListActivity:

Step 3: Create our custom ListView item

Right-click on the layout folder within res and select new > layout resource file:

After naming our list item, we can customize it to our liking:

In this example, my list-view item contains a TextView and some ImageViews. We will eventually be able to set these in our Adapter class.

Step 4: Make your Data types parcelable

When working with large sets of data, we often need to pass this data from one activity to another (think prepareForSegue() in iOS). In Android, we accomplish this through wrapping and unwrapping Parcelable data.

A. First, your data classes must extend Parcelable:

B. Furthermore, they must implement the required writeToParcel(Parcel dest, int flags) method. Notice below that it should write each member variable of the class that will need to be unwrapped elsewhere.

C. Additionally, you want to add a private constructor that takes a Parcel object as a parameter, and reads (as opposed to writes, as we did above) each member variable. And the order in which we read each member variable must be the same as it is in writeToParcel(Parcel dest, int flags):

In these examples, my custom data class is named Day

D. Now we just need to a Creator constant, which essentially becomes the constructor, which generates instances of our Parcelable class from a Parcel:

In these examples, my custom data class is named Day.

Through making our data types parcelable, we are allowing their data to be wrapped up, shipped out, and ultimately unwrapped by other files.

E. Here’s how it will look when we unwrap the data in our ListView activity:

Important to note is the conversion from Parcelable array to the certain array type we actually need (in this case an array of Day objects). Arrays.copyOf() makes this conversion possible.

Step 5: Create a custom Adapter

Adapters act as a bridge between our data and our view (think MVC). In this example we will subclass the most basic of adapter classes for simplicity: BaseAdapter.

In this example, my adapter communicates data about certain days of the week (or, Day objects) to my ListView. So I’ve named it DayAdapter.

A. Our adapter will need two specific pieces of information: a context and its data:

In this example, our data is the array of Day objects.

We’ll then need to override two important methods based on the data we are using:

B. The next component our Adapter class needs is a ViewHolder.

The ViewHolder design-pattern is considered best-practice, as it allows for efficient reuse of our views, eliminating the need to call findViewById() for each item in our list-view.

We can create the ViewHolder directly within our Adapter class

Now, in the getView(int position, View convertView, ViewGroup parent) is where the magic happens, and we set each item in our list-view to display the appropriate data:

Recap: Working with large data sets and efficiently setting views with this data can seem overwhelming at first. However, once you break down the process and understand the different parts at work (ListView, Adapter and ViewHolder, and Parcelable data types) you have all you need to create powerful Android applications.

If you’d like to reference a basic example, here is the code from a simple project I made to demonstrate ListViews and Adapters.

Note: ListView is not the only option for displaying large sets of data! RecyclerView, for example, is a new alternative that offers many advantages when displaying collections of data. I will tackle RecyclerView in a future post so be on the lookout.