Android Dev: Custom ListAdapter

11 March 2010 ,    1 Comment

Disclaimer: This post presumes you’ve setup the Android SDK and Eclipse. If not, check out the Android Developer Guide

Some of the Android developer documents seem great, but in general there seems to be a lacking of documentation/examples – while the Java language is giving me no problems, how to do things with the Android API can be a bit of a nightmare to figure out.

It is possibly because Android is relatively new or because I’m used to MSDN which is a fantastic resource. Regardless, I started to want to develop MahTweetsMobile for Android and was having difficulty in ‘binding’ a ‘view’ to a list of elements, ala WPF/XAML’s DataTemplates.

It turns out its not as magical as what WPF is and requires manual binding, but its not impossible.

The View

To get a list to display anything other than just a string, you need to define your own view in either XML or code-behind. I find XML to be a little nicer, and its easier to update.

In Eclipse (I’m sure it’ll work in other IDE’s too, but this is what I’m using), you can create a new view by navigating to res –> layout, right clicking on the folder and selecting New –> Other, then from the popup select Android –> Android XML File

image

Make sure in the next dialog you select the Layout resource type, and give the file a name like "tweetview.xml" (all in lower case, as java/ADK will complain otherwise).

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
android:id="@+id/widget32"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical"
xmlns:android="http://schemas.android.com/apk/res/android"
>
<TableLayout
android:id="@+id/widget33"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical"
>
<TableRow
android:id="@+id/widget35"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
>
<ImageButton
android:id="@+id/imgbtnAvatar"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
>
</ImageButton>
<LinearLayout
android:id="@+id/widget39"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical"
>
<TextView
android:id="@+id/txtName"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="TextView"
>
</TextView>
<TextView
android:id="@+id/txtTweet"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="TextView"
>
</TextView>
</LinearLayout>
</TableRow>
</TableLayout>
</LinearLayout>

The Model

Just a simple class to hold our data,

package mahapps.MahTweets;

import java.util.Date;

public class Tweet {
    public int ID;
    public String Name;
    public String Text;
    public Date Timestamp;

    public int getID()
    {
        return this.ID;
    }

    public String getName()
    {
        return this.Name;
    }

    public String getText()
    {
        return this.Text;
    }

    public Tweet()
    {

    }
}

The Custom ListAdapter

This is the "heavy lifting" code – this is what "binds" a Tweet object to the TweetView.

package mahapps.MahTweets;

import android.content.Context;
import android.view.View;
import android.view.ViewGroup;
import android.widget.*;
import java.util.*;

public class TweetAdapter extends BaseAdapter
{
    private List<Tweet> elements;
    private Context c;

    public TweetAdapter(Context c, List<Tweet> Tweets)
    {
        this.elements = Tweets;
        this.c = c;
    }
    public int getCount() {

        return elements.size();
    }

    public Object getItem(int position) {

        return elements.get(position);
    }

    public long getItemId(int id) {

        return id;
    }

    public void Remove(int id)
    {
        notifyDataSetChanged();
    }
    public View getView(int position, View convertView, ViewGroup parent)
    {

        LinearLayout rowLayout;
        Tweet t = elements.get(position);

        if (convertView == null)
        {
            rowLayout = (LinearLayout)LayoutInflater.from(c).inflate
                      (R.layout.TweetListView, parent, false);
           TextView tv = (TextView)rowLayout.findViewById(R.id.txtName);
           tv.setText(t.getText());

           //...
           //and so on for all the properties/UI elements
           //...

        } else {
            rowLayout = (RelativeLayout)convertView;
        }
        return rowLayout;
    }
}

 

You can then use this in your main Activity:

ListView x = (ListView)findViewById(R.id.ListView01);
x.setAdapter(new TweetAdapter(this, MyListOfTweets));

If you’re using a ListActivity, you’d just set that Activity’s adapter.

Your ListView items should then appear in more detail!

image


Comments

One Comment

Trackbacks / Pingbacks

Leave a Reply