Wednesday, June 19, 2013

Howto - Create a custom Android ListAdapter

Create a custom ListAdapter

Properly the easiest way to populate a List (e.g. ListActivity) is to use the ArrayAdapter as …



ArrayAdapter<Rate> adapter = new ArrayAdapter<Rate>(this,aLayoutResourceId, aTextViewId, Rate[]);

this.setListAdapter(adapter);



When the ListView render, the toString() method of the Rate class is invoked to populate the text content of the TextView. We can override the toString() method to format its output. However, this is limited basic as it can only output plain text string. By creating a custom ListAdapter, we have full control on the view of list item.


1. Define the list item layout xml

In our example (i.e. rate_row.xml), each list item has two rows, the top row show the rate supplier and the bottom row show four numbers for the rate details

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

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

android:orientation="vertical" android:layout_width="fill_parent"

android:layout_height="wrap_content">

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

android:orientation="horizontal"

android:layout_width="fill_parent"

android:layout_height="wrap_content">

<TextView

android:id="@+id/rate_supplier"

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:text="@string/supplier" />

</LinearLayout>

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

android:orientation="horizontal"

android:layout_width="fill_parent"

android:layout_height="wrap_content">

<TextView

android:id="@+id/rate_rate1"

android:layout_width="80px"

android:layout_height="wrap_content"

android:layout_gravity="right"

android:text="@string/rate1" />

<TextView

android:id="@+id/rate_rate2"

android:layout_width="80px"

android:layout_height="wrap_content"

android:layout_gravity="right"

android:text="@string/rate2" />

<TextView

android:id="@+id/rate_points"

android:layout_width="80px"

android:layout_height="wrap_content"

android:layout_gravity="right"

android:text="@string/points" />

<TextView

android:id="@+id/rate_lockdays"

android:layout_width="80px"

android:layout_height="wrap_content"

android:layout_gravity="right"

android:text="@string/lockdays" />

</LinearLayout>

</LinearLayout>

2. Create a subclass from ArrayAdapter

Besides of Constructors, there’s only one method (i.e. getView) really need to implement. The getView(…) method is called on each member of the given object array with position as its index in the array.

The only tricky part is the given convertView could be null. We need to have null check on it and inflate a view.

public class RateListAdapter extends ArrayAdapter<Rate>{

protected View getView(int position, View convertView, ViewGroup parent) {

View aView=null;

if(convertView==null){

LayoutInflater aInflater=LayoutInflater.from(getContext());

aView=aInflater.inflate(R.layout.rates_row,parent,false);

} else {

aView=convertView;

}

Rate aRate=getItem(position);

TextView supplier=(TextView)aView.findViewById(R.id.rate_supplier);

supplier.setText(aRate.getSupplier());

….

return aView;

}