Customizing Android ListView

Spanish

This document describes how to build a custom list view in Android. In this case,  2 rows and 1 image will be displayed in the list view. It is assumed that the reader has basic knowledge on the Android OS.

The following libraries and applications are used:

– Windows 7

– Eclipse Galileo (Android DDMS, Android Development Tools)

1.1) First, create an Android project. If the plugin was properly installed, you should see “Android Project” listed as one of the options available:

image_thumb

1.2) You can put any name for the project, in my case, I called it CustomListView. The android version specified is 2.3, but the code should work correctly on earlier versions. In the “Properties” section, you must provide the application name, package name and the activity name. These fields were filled out as follows: Custom ListView, com.customlv.test, LVMain.

image

If you want to create an Android test project, click on NEXT, otherwise select FINISH.

1.3) Eclipse automatically creates a skeleton and updates the AndroidManifest file. Next, you must update the application layout (res->layout->main.xml) and add the objects we need: ImageView and TextView:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:padding="6dip">
    <ImageView
        android:id="@+id/myimage"
        android:layout_width="wrap_content"
        android:layout_height="fill_parent"
        android:layout_marginRight="6dip"/>
    <LinearLayout
        android:orientation="vertical"
        android:layout_width="0dip"
        android:layout_weight="1"
        android:layout_height="fill_parent">
        <TextView android:id="@+id/line1"
            android:layout_width="fill_parent"
            android:layout_height="0dip"
            android:layout_weight="1"
            android:gravity="center_vertical"/>
        <TextView android:id="@+id/line2"
            android:layout_width="fill_parent"
            android:layout_height="0dip"
            android:layout_weight="1"
            android:singleLine="true"
            android:ellipsize="marquee"/>
    </LinearLayout>
</LinearLayout>

1.4) The ListView object is populated with an adapter. There are different types of adapters (ArrayAdapter, CursorAdapter, etc) and all of them extend from the BaseAdapter class. To customize our list view, we need to create a custom adapter; so, let’s start by adding this class (MyCustomAdapter) to the project:

image

There are 4 methods which must be overridden:

  • getCount: returns the total number of items listed.
  • getItem: returns an item based on the given index.
  • getItemId: returns the row’s id.
  • getView: returns a View object that displays the data at the specified position.

1.5) There are two major components which must be added to this code: the Layout inflater and a collection object to store the items (or it can be a Cursor, if the values come from a database). The LayoutInflater object will act as the bridge between your layout’s xml code and the View objects. The collection (for this example it is an ArrayList) stores all the items that will be added to the list view. During the instantiation of the MyCustomAdapter object, the context’s inflater will be referenced and the data to be displayed will be passed as input.

public class MyCustomAdapter extends BaseAdapter {

	private LayoutInflater li;
	private List<User> users = new ArrayList<User>();

	public MyCustomAdapter(Context context, List<User> items)
	{
		li = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
		if(items != null)
			users = items;
	}

....

For this example, I will be passing a List of User objects as input. This class will be defined later.

1.6) The first 3 methods (getCount, getItem, getItemId) are defined as follows:
....
  @Override
	public int getCount() {
		return users.size();
	}

	@Override
	public Object getItem(int position) {
		return users.get(position);
	}

	@Override
	public long getItemId(int position) {
		return position;
	}

....

This code is straightforward. The returned values are based on the List object received as input. The first method returns the size of this object; the getItem method returns the object stored at a given index. Finally, the getItemId method returns the same value that is received as input (this is the row that was clicked).

1.7) Next, the getView method is defined. This method does all the hard work and converts each item into a View object:

...
@Override
	public View getView(int position, View convertView, ViewGroup parent) {
		//current view object
		View v = convertView;

		final User user = users.get(position);

		//if View exists, then reuse... else create a new object.
		if (v == null) {
			v = li.inflate(com.customlv.test.R.layout.main, null);
		}

		//reference to the ImageView component
		final ImageView mLogo = (ImageView)v.findViewById(com.customlv.test.R.id.myimage);

		//if gender is male, then use 'male' icon. Otherwise, female.
		if(user.getSex().equals("male"))
			mLogo.setImageResource(com.customlv.test.R.drawable.male);
		else
			mLogo.setImageResource(com.customlv.test.R.drawable.female);

		//set 'name' in line 1.
		final TextView nameTv = (TextView) v.findViewById(com.customlv.test.R.id.line1);
		nameTv.setText(user.getName());

		//set 'gender' in line 2.
		final TextView genderTv = (TextView) v.findViewById(com.customlv.test.R.id.line2);
		genderTv.setText(user.getSex());

		return v;
	}
...

The method receives as input a View object; if it is already instantiated, then it is reused. Otherwise, a new View object is declared. Two images can be displayed, and it will depend on the user’s gender.

1.8) Next, we will add the objects that will be consumed by our ListView. Add a new class called User and add the following methods to it:

public class User {

	private String name;
	private String sex;

   public User(){}

	public User(String name, String sex)
	{
		setName(name);
		setSex(sex);
	}

	public String getName() {
		return name;
	}
	public String getSex() {
		return sex;
	}
	public void setName(String name) {
		this.name = name;
	}
	public void setSex(String sex) {
		this.sex = sex;
	}

}

1.9) Finally, lets test our custom list view. To do this, go back to the main activity (LVMain) and add the following code:

public class LVMain extends ListActivity {
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        List<User> users = new ArrayList<User>();
        users.add(new User("john", "male"));
        users.add(new User("mary","female"));
        users.add(new User("bob","male"));

        setListAdapter(new MyCustomAdapter(this, users));
    }
}

1.10) Run the emulator and the following list will be displayed:

image

Advertisements

2 responses to “Customizing Android ListView

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: