Android – Customizing list view item layout

Android – Customizing list view item layout

In a previous article I described how to use a ListView to display data. In the example the data was shows using a string without any formatting. This article will show you how to change the code so the data will be shown in a better looking way. The data will be formatted by using a custom ArrayAdapter which will use a custom item layout.

Let’s start with the basics: the main.xml and the used data class.

main.xml:

[xml highlight=”16,17-20″]

<?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=”fill_parent”
>
<TextView
android:id=”@+id/header”
android:layout_width=”fill_parent”
android:layout_height=”wrap_content”
android:gravity=”center_vertical|center_horizontal”
android:textSize=”20sp”
android:textColor=”#FF0000″
android:text=”ListView using standard ArrayAdapter and simple list layout”
/>
<ListView
android:id=”@+id/list”
android:layout_width=”fill_parent”
android:layout_height=”wrap_content”
/>
</LinearLayout>

[/xml]

The following code shows the data class which will hold the temperature data.

TemperatureData.java:

[java highlight=”14,15-37″]

package nl.jestersoft.listviewtryout;

import android.text.format.Time;

public class TemperatureData
{
// The data
String SensorName;
double CurrentTemperature;
double MinimumTemperature;
double MaximumTemperature;
String TimeStamp;

public String GetSensorName()
{
return SensorName;
}

public double GetCurrentTemperature()
{
return CurrentTemperature;
}

public double GetMinimumTemperature()
{
return MinimumTemperature;
}

public double GetMaximumTemperature()
{
return MaximumTemperature;
}

public String GetTimeStamp()
{
return TimeStamp;
}

public TemperatureData(String sensorName, double currentTemperature, double minimumTemperature, double maximumTemperature, String timeStamp )
{
SensorName = sensorName;
CurrentTemperature = currentTemperature;
MinimumTemperature = minimumTemperature;
MaximumTemperature = maximumTemperature;
TimeStamp = timeStamp;
}

@Override
public String toString()
{
String item;

// Just out out the data as a string
item = SensorName + “: ” + CurrentTemperature + “, ” + MinimumTemperature + “, ” + MaximumTemperature + ” (” + TimeStamp + “)”;

return item;
}
}
[/java]

The data class has been extended with public methods so we can access the internal data fields. Below the adjusted main code is shown.

ListViewTryout.java:

[java highlight=”25,26,27″]
package nl.jestersoft.listviewtryout;

import java.util.ArrayList;
import java.util.List;

import android.app.Activity;
import android.os.Bundle;
import android.widget.*;

public class ListViewTryout extends Activity {
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.main);

// Add some dummy data to the list
ArrayList<TemperatureData> tempData = GetDummyData();

// Get list to view data in
ListView list = (ListView)findViewById(R.id.list);

// Show data in the list
int layoutID = R.layout.listitem;
TemperatureAdapter tempAdapter = new TemperatureAdapter(this, layoutID, tempData);
list.setAdapter(tempAdapter);
}

public ArrayList<TemperatureData> GetDummyData()
{
ArrayList<TemperatureData> dummyData = new ArrayList<TemperatureData>();

TemperatureData data1 = new TemperatureData(“Balcony”, 18.0, 16.0, 20.0, “30-07-2011 13:14”);
dummyData.add(data1);

TemperatureData data2 = new TemperatureData(“Living room”, 24.0, 20.0, 25.0, “30-07-2011 13:14”);
dummyData.add(data2);

TemperatureData data3 = new TemperatureData(“Bath room”, 18.0, 21.0, 27.0, “30-07-2011 13:15”);
dummyData.add(data3);

return dummyData;
}
[/java]

In this version of the main code we are not using the standard ArrayAdapter but a custom adapter (TemperatureAdapter). The adapter is now using a custom layout (R.layout.listitem) instead of the simple list item layout. Below the code for the custom adapter and list item layout is shown.

listitem.xml

[xml]

<?xml version=”1.0″ encoding=”utf-8″?>
<LinearLayout
xmlns:android=”http://schemas.android.com/apk/res/android”
android:id=”@+id/layout”
android:orientation=”horizontal”
android:layout_width=”fill_parent”
android:layout_height=”fill_parent”
>

<!– Column 1 –>
<TextView
android:id=”@+id/currentTemp”
android:layout_width=”wrap_content”
android:layout_height=”fill_parent”
android:gravity=”center_vertical|center_horizontal”
android:layout_weight=”1″
android:textStyle=”bold”
android:textSize=”28sp”
android:text=”18″/>

<!– Column 2 –>
<TableLayout
android:layout_height=”fill_parent”
android:layout_width=”wrap_content”
android:layout_weight=”1″>
<TableRow>
<TextView
android:id=”@+id/sensorDescr”
android:layout_width=”wrap_content”
android:layout_height=”wrap_content”
android:gravity=”center”
android:textSize=”16sp”
android:text=”Balkon”/>
</TableRow>
<TableRow>
<TextView
android:id=”@+id/timestamp”
android:layout_width=”fill_parent”
android:layout_height=”wrap_content”
android:gravity=”center”
android:textSize=”8sp”
android:text=”30-07-2011 13:14″/>
</TableRow>
</TableLayout>

<!– Column 3 –>
<TableLayout
android:layout_width=”wrap_content”
android:layout_height=”wrap_content”
android:gravity=”right”>
<TableRow>
<TextView
android:id=”@+id/maxLabel”
android:layout_width=”fill_parent”
android:layout_height=”wrap_content”
android:gravity=”bottom”
android:textSize=”8sp”
android:text=”max”/>
<TextView
android:id=”@+id/maxTemp”
android:layout_width=”wrap_content”
android:layout_height=”wrap_content”
android:gravity=”right”
android:textSize=”14sp”
android:layout_margin=”1dip”
android:textStyle=”bold”
android:text=”20″/>
</TableRow>
<TableRow>
<TextView
android:id=”@+id/minLabel”
android:layout_width=”fill_parent”
android:layout_height=”wrap_content”
android:gravity=”bottom”
android:textSize=”8sp”
android:text=”min”/>
<TextView
android:layout_height=”wrap_content”
android:text=”16″
android:textSize=”14sp”
android:layout_width=”fill_parent”
android:layout_margin=”1dip”
android:textStyle=”bold”
android:id=”@+id/minTemp”></TextView>
</TableRow>
</TableLayout>
</LinearLayout>
[/xml]

You can create a layout just the way you want it. The custom adapter will ensure that the data will be displayed in the layout.

TemperatureAdapter.java

[java highlight=”34,35,38,62″]
package nl.jestersoft.listviewtryout;

import java.util.ArrayList;
import java.util.List;

import android.content.Context;
import android.view.InflateException;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.LinearLayout;
import android.widget.TextView;

public class TemperatureAdapter extends ArrayAdapter<TemperatureData>
{
private ArrayList<TemperatureData> items;
private Context context;

public TemperatureAdapter(Context context, int resource, ArrayList<TemperatureData> items)
{
super(context, resource, items);
this.items = items;
this.context = context;
}

@Override
public View getView(int position, View convertView, ViewGroup parent)
{
View temperatureView = convertView;

if ( temperatureView == null)
{
LayoutInflater inflator = (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
temperatureView = inflator.inflate(R.layout.listitem, null);
}

TemperatureData item = this.items.get(position);

String sensorName = item.GetSensorName();
double currentTemperature = item.GetCurrentTemperature();
double minimumTemperature = item.GetMinimumTemperature();
double maximumTemperature = item.GetMaximumTemperature();
String timeStamp = item.GetTimeStamp();

TextView tvCurrentTemp = (TextView)temperatureView.findViewById(R.id.currentTemp);

TextView tvSensorDescr = (TextView)temperatureView.findViewById(R.id.sensorDescr);
TextView tvTimestamp = (TextView)temperatureView.findViewById(R.id.timestamp);
TextView tvMinTemp = (TextView)temperatureView.findViewById(R.id.minTemp);
TextView tvMaxTemp = (TextView)temperatureView.findViewById(R.id.maxTemp);

tvCurrentTemp.setText(String.valueOf(currentTemperature));
tvSensorDescr.setText(sensorName);
tvTimestamp.setText(timeStamp);

String min = String.valueOf(minimumTemperature);
tvMinTemp.setText(min);
String max = String.valueOf(maximumTemperature);
tvMaxTemp.setText(max);

return temperatureView;
}
}
[/java]

The most important code in this class is where an inflator is created and used to load the custom list item layout.

When you run the code you will see the following result.

Comments are closed.