This tutorial will walk you through building a custom multi-line ListView in Android.
We’ll achieve this by extending BaseAdapter (or concrete ArrayAdapter) to turn a collection of objects into individual ListView items.
First, let’s define the layout for our scrollable ListView by placing the following in main.xml:
[xml]
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:gravity="center_vertical|center_horizontal"
android:text="Custom ListView Example" />
<ListView
android:id="@+id/srListView"
android:layout_width="fill_parent"
android:layout_height="fill_parent" />
</LinearLayout>
[/xml]
Next, let’s define a layout for individual ListView items. Paste this layout code in a new layout file called custom_row_view.xml:
[xml]
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical"
android:paddingBottom="10dip"
android:paddingLeft="10dip"
android:paddingTop="10dip" >
<TextView
android:id="@+id/name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="#C20000"
android:textSize="14sp"
android:textStyle="bold" />
<TextView
android:id="@+id/cityState"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<TextView
android:id="@+id/phone"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</LinearLayout>
[/xml]
Next, let’s create a POJO called SearchResults.java to represent contact search results. Paste this boilerplate code into it:
[java]
package com.publicstaticdroidmain.android;
public class SearchResults {
private String name = "";
private String cityState = "";
private String phone = "";
public void setName(String name) {
this.name = name;
}
public String getName() {
return name;
}
public void setCityState(String cityState) {
this.cityState = cityState;
}
public String getCityState() {
return cityState;
}
public void setPhone(String phone) {
this.phone = phone;
}
public String getPhone() {
return phone;
}
}
[/java]
Now we need to build an Adapter. The Adapter will turn our collection of SearchResults into individual ListView items. Create a file called MyCustomBaseAdapter.java with these contents:
[java]
package com.publicstaticdroidmain.android;
import java.util.ArrayList;
import com.publicstaticdroidmain.R;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.TextView;
public class MyCustomBaseAdapter extends BaseAdapter {
private static ArrayList<SearchResults> searchArrayList;
private LayoutInflater mInflater;
public MyCustomBaseAdapter(Context context, ArrayList<SearchResults> results) {
searchArrayList = results;
mInflater = LayoutInflater.from(context);
}
public int getCount() {
return searchArrayList.size();
}
public Object getItem(int position) {
return searchArrayList.get(position);
}
public long getItemId(int position) {
return position;
}
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder;
if (convertView == null) {
convertView = mInflater.inflate(R.layout.custom_row_view, null);
holder = new ViewHolder();
holder.txtName = (TextView) convertView.findViewById(R.id.name);
holder.txtCityState = (TextView) convertView
.findViewById(R.id.cityState);
holder.txtPhone = (TextView) convertView.findViewById(R.id.phone);
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
holder.txtName.setText(searchArrayList.get(position).getName());
holder.txtCityState.setText(searchArrayList.get(position)
.getCityState());
holder.txtPhone.setText(searchArrayList.get(position).getPhone());
return convertView;
}
static class ViewHolder {
TextView txtName;
TextView txtCityState;
TextView txtPhone;
}
}
[/java]
And finally, let’s update our main Activity class (mine is called CustomListViewActivity) to tie everything together:
[java]
package com.publicstaticdroidmain.android;
import java.util.ArrayList;
import com.publicstaticdroidmain.R;
import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.ListView;
import android.widget.Toast;
public class CustomListViewActivity extends Activity {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
ArrayList<SearchResults> searchResults = GetSearchResults();
final ListView lv = (ListView) findViewById(R.id.srListView);
lv.setAdapter(new MyCustomBaseAdapter(this, searchResults));
lv.setOnItemClickListener(new OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> a, View v, int position, long id) {
Object o = lv.getItemAtPosition(position);
SearchResults fullObject = (SearchResults)o;
Toast.makeText(CustomListViewActivity.this, "You have chosen: " + " " + fullObject.getName(), Toast.LENGTH_LONG).show();
}
});
}
private ArrayList<SearchResults> GetSearchResults(){
ArrayList<SearchResults> results = new ArrayList<SearchResults>();
SearchResults sr = new SearchResults();
sr.setName("Justin Schultz");
sr.setCityState("San Francisco, CA");
sr.setPhone("415-555-1234");
results.add(sr);
sr = new SearchResults();
sr.setName("Jane Doe");
sr.setCityState("Las Vegas, NV");
sr.setPhone("702-555-1234");
results.add(sr);
sr = new SearchResults();
sr.setName("Lauren Sherman");
sr.setCityState("San Francisco, CA");
sr.setPhone("415-555-1234");
results.add(sr);
sr = new SearchResults();
sr.setName("Fred Jones");
sr.setCityState("Minneapolis, MN");
sr.setPhone("612-555-8214");
results.add(sr);
sr = new SearchResults();
sr.setName("Bill Withers");
sr.setCityState("Los Angeles, CA");
sr.setPhone("424-555-8214");
results.add(sr);
sr = new SearchResults();
sr.setName("Donald Fagen");
sr.setCityState("Los Angeles, CA");
sr.setPhone("424-555-1234");
results.add(sr);
sr = new SearchResults();
sr.setName("Steve Rude");
sr.setCityState("Oakland, CA");
sr.setPhone("515-555-2222");
results.add(sr);
sr = new SearchResults();
sr.setName("Roland Bloom");
sr.setCityState("Chelmsford, MA");
sr.setPhone("978-555-1111");
results.add(sr);
sr = new SearchResults();
sr.setName("Sandy Baguskas");
sr.setCityState("Chelmsford, MA");
sr.setPhone("978-555-2222");
results.add(sr);
sr = new SearchResults();
sr.setName("Scott Taylor");
sr.setCityState("Austin, TX");
sr.setPhone("512-555-2222");
results.add(sr);
return results;
}
}
[/java]
And that’s it. If you’ve done everything correctly, you should wind up with this:
Here’s the zipped source code.
Leave a Reply