Android - Create a custom multi-line ListView bound to an ArrayList

The Android HelloListView tutorial shows how to bind a ListView to an array of string objects, but you'll probably outgrow that pretty quickly. This post will show you how to bind the ListView to an ArrayList of custom objects, as well as create a multi-line ListView.

Let's say you have some sort of search functionality that returns a list of people, along with addresses and phone numbers. We're going to display that data in three formatted lines for each result, and make it clickable.

First, create your new Android project, and create two layout files. Main.xml will probably already be created by default, so paste this in:

<?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:layout_height="wrap_content"
  android:text="Custom ListView Contents"
  android:gravity="center_vertical|center_horizontal"
  android:layout_width="fill_parent" />
  <ListView
   android:id="@+id/ListView01"
   android:layout_height="wrap_content"
   android:layout_width="fill_parent"/>
</LinearLayout>

Next, create a layout file called custom_row_view.xml. This layout will be the template for each individual row in the ListView. You can use pretty much any type of layout - Relative, Table, etc., but for this we'll just use Linear:

<?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/name"
  android:textSize="14sp"
  android:textStyle="bold"
  android:textColor="#FFFF00"
  android:layout_width="wrap_content"
  android:layout_height="wrap_content"/>
 <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>

Now, add an object called SearchResults. Paste this code in:

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;
 }
}


This is the class that we'll be filling with our data, and loading into an ArrayList.

Next, you'll need a custom adapter. This one just extends the BaseAdapter, but you could extend the ArrayAdapter if you prefer.

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;
 }
}

(This is basically the same as the List14.java API demo)

Finally, we'll wire it all up in the main class file:

public class CustomListView extends Activity {
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
       
        ArrayList<SearchResults> searchResults = GetSearchResults();
       
        final ListView lv1 = (ListView) findViewById(R.id.ListView01);
        lv1.setAdapter(new MyCustomBaseAdapter(this, searchResults));
       
        lv1.setOnItemClickListener(new OnItemClickListener() {
         @Override
         public void onItemClick(AdapterView<?> a, View v, int position, long id) {
          Object o = lv1.getItemAtPosition(position);
          SearchResults fullObject = (SearchResults)o;
          Toast.makeText(ListViewBlogPost.this, "You have chosen: " + " " + fullObject.getName(), Toast.LENGTH_LONG).show();
         } 
        });
    }
   
    private ArrayList<SearchResults> GetSearchResults(){
     ArrayList<SearchResults> results = new ArrayList<SearchResults>();
     
     SearchResults sr1 = new SearchResults();
     sr1.setName("John Smith");
     sr1.setCityState("Dallas, TX");
     sr1.setPhone("214-555-1234");
     results.add(sr1);
     
     sr1 = new SearchResults();
     sr1.setName("Jane Doe");
     sr1.setCityState("Atlanta, GA");
     sr1.setPhone("469-555-2587");
     results.add(sr1);
     
     sr1 = new SearchResults();
     sr1.setName("Steve Young");
     sr1.setCityState("Miami, FL");
     sr1.setPhone("305-555-7895");
     results.add(sr1);
     
     sr1 = new SearchResults();
     sr1.setName("Fred Jones");
     sr1.setCityState("Las Vegas, NV");
     sr1.setPhone("612-555-8214");
     results.add(sr1);
     
     return results;
    }
}

Notice that we first get an ArrayList of SearchResults objects (normally this would be from an external data source...), pass it to the custom adapter, then set up a click listener. The listener gets the item that was clicked, converts it back to a SearchResults object, and does whatever it needs to do.

Fire it up in the emulator, and you should wind up with something like this:

Update (2/22/2012): I've uploaded a complete Eclipse project of this tutorial to Dropbox: ListViewBlogPost.zip

Technorati Tags:

Print | posted @ Monday, January 31, 2011 3:33 PM

Comments on this entry:

Gravatar # re: Android - Create a custom multi-line ListView bound to an ArrayList
by hyunjungsoh at 2/6/2011 5:47 PM

Thank you! Been looking all over for this! :)
Gravatar # re: Android - Create a custom multi-line ListView bound to an ArrayList
by Sigit at 2/12/2011 2:30 PM

I've found many tutorial with same the subject, but I think this one I can "follow" easily. Thx man, you rocks!
Gravatar # re: Android - Create a custom multi-line ListView bound to an ArrayList
by vicman at 3/17/2011 10:21 AM

Excelent article. Thanks
Gravatar # re: Android - Create a custom multi-line ListView bound to an ArrayList
by Firas ayed at 4/4/2011 3:14 PM

comment faire pour avoir une Listview aved différente ligne....
Gravatar # re: Android - Create a custom multi-line ListView bound to an ArrayList
by subktageen at 4/8/2011 12:49 PM

Great work .....
Its so simple and easy in understanding
Gravatar # re: Android - Create a custom multi-line ListView bound to an ArrayList
by Stefan den Hartog at 6/22/2011 1:22 PM

I followed your tutorial and it works good.
But loading the list items take a long time, and sometimes it only shows the first item and the last item and only after I scroll a few times it shows them all..

Do you know why this happens?
Gravatar # re: Android - Create a custom multi-line ListView bound to an ArrayList
by Bill at 6/23/2011 9:41 AM

I'd have to guess that it's something to do with the way the ArrayList is getting created... I've used this method in half a dozen different apps and have never seen behavior like that.
Gravatar # re: Android - Create a custom multi-line ListView bound to an ArrayList
by Renjith at 7/1/2011 8:12 AM

Thanks for the wonderful tutorial.
Well, I tried to tweak an icon into this layout. I was modifying the layout in such as way that each row has an icon followed by a name, vertically aligned to country and phone info. However I could not make that work. Could you please shed some light on it.
Gravatar # re: Android - Create a custom multi-line ListView bound to an ArrayList
by nik at 7/13/2011 8:49 PM

Thanks for the tutorial. I've followed your steps and I can recreate your output. I've also added some functionality that when one item is clicked, I spawn a new activity. That works fine too. Once I'm in the new Activity and I press the back button, it takes me to this view and if I do anything to it, it crashes. Would you know why? If I use a simple ArrayListAdapter it works just fine. Could it be the way you handle the view in your custom Adapter?
Gravatar # re: Android - Create a custom multi-line ListView bound to an ArrayList
by Bill at 7/15/2011 8:28 AM

Without seeing code it's hard to say, but it could be the way you're creating the new activity. I'm doing the same thing in a few apps without any problem.

Inside my onItemClick I'm doing this:

Object o = lv1.getItemAtPosition(position);
SearchResults fullObject = (SearchResults)o;

Intent intent = new Intent(CurrentActivity.this, NewActivity.class);
Bundle b = new Bundle();

b.putString("name", fullObject.getName());

intent.putExtras(b);
startActivity(intent);

("CurrentActivity" is the name of the activity I'm in, and "NewActivity" is the one I want to start)

...and I can hop back and forth with no problem.

Have you tried watching the execution using logcat?
Gravatar # re: Android - Create a custom multi-line ListView bound to an ArrayList
by nik at 7/17/2011 12:18 PM

Thanks for your reply. There is nothing wrong with the code, it works great. When I started the new activity I did it using the same xml layout thus ended up modifying the same listview. So after going back, I got an error for modifying the listview in a child thread. Everything now works as expected. Thanks again.
Gravatar # Searchable List View
by RojyGeorge at 8/23/2011 3:23 AM

Nice Tutorial (*!*) so simply explained
How to attach a search dialog,so that we can search list items based on name
Gravatar # re: Android - Create a custom multi-line ListView bound to an ArrayList
by Glenn at 8/27/2011 1:37 PM

Tried you example - but, it does not work.
After importing what was needed, I still end up with:
* ListViewBlogPost cannot be resolved to a type
* OnItemClickListener cannot be resolved to a type
* searchResults cannot be resolved
* The field searchArrayList cannot be declared static; static fields can only be declared in static or top level types
* The field searchArrayList cannot be declared static; static fields can only be declared in static or top level types
* The member type ViewHolder cannot be declared static; static types can only be declared in static or top level types
* The member type ViewHolder cannot be declared static; static types can only be declared in static or top level types
Maybe you could upload a complete, working example?
Gravatar # re: Android - Create a custom multi-line ListView bound to an ArrayList
by Rich at 9/20/2011 3:06 AM

Great post thanks
@Glenn replace ListViewBlogPost with getApplicationContext() and that will sort that problem out; the rest of your issues are probably due to imports and not having other classes in the same package etc.
You do need some Java experience to code for Android :-)
Gravatar # re: Android - Create a custom multi-line ListView bound to an ArrayList
by nyom2 at 10/15/2011 10:29 AM

thanks mate :)
Gravatar # re: Android - Create a custom multi-line ListView bound to an ArrayList
by hussainkothari at 10/18/2011 4:33 AM

I had to modify the CustomListView.java to get rid of the compilation errors. Modified stmts -

lv1.setOnItemClickListener(new AdapterView.OnItemClickListener() {
public void onItemClick(AdapterView<?> a, View v, int position, long id) {
Gravatar # re: Android - Create a custom multi-line ListView bound to an ArrayList
by Josef Halicek at 10/29/2011 7:22 PM

Thank you very much, finally tutorial which showed me doable way.
Gravatar # re: Android - Create a custom multi-line ListView bound to an ArrayList
by Aaron at 11/14/2011 5:47 PM

I'm writing my first Android App. I'm coming from a C# background (10 years). I'm glad I found this post because it really cleared some fundamental issues up for me.

Thanks. It works like a charm.
Gravatar # re: Android - Create a custom multi-line ListView bound to an ArrayList
by priya at 11/29/2011 12:31 AM

Thank you very much for such a great post. It provides the structured way for binding multiple data items in an ArrayList to ListView.
Gravatar # re: Android - Create a custom multi-line ListView bound to an ArrayList
by Anil at 12/12/2011 5:25 AM

This was nice . psot iw as new in android but from this Example i did 2 application...and now its running in market..
Gravatar # re: Android - Create a custom multi-line ListView bound to an ArrayList
by Sergio at 12/18/2011 9:40 AM

Great post!
Gravatar # re: Android - Create a custom multi-line ListView bound to an ArrayList
by John mcClane at 1/6/2012 1:53 AM

This is really great, thanks a lot!
Gravatar # re: Android - Create a custom multi-line ListView bound to an ArrayList
by daca at 1/6/2012 4:03 PM

great tuto! But how to add pictures with listview??
Gravatar # re: Android - Create a custom multi-line ListView bound to an ArrayList
by wasif hamdani at 1/9/2012 7:23 AM

its very simple and really great tutorial for novice users.
Gravatar # re: Android - Create a custom multi-line ListView bound to an ArrayList
by Nuno Horta at 1/13/2012 9:39 AM

Thanks for the tutorial!! But i have and error :

No enclosing instance of type MyCustomBaseAdapter is accessible. Must qualify the allocation with an enclosing instance of type MyCustomBaseAdapter (e.g. x.new A() where x is an instance of MyCustomBaseAdapter).

Can anyone help me? This error is on the line: sr1 = new SearchResults();
Gravatar # re: Android - Create a custom multi-line ListView bound to an ArrayList
by Mike at 1/15/2012 10:58 PM

This is really great work, thanks. Android should consider adding this tutorial to their docs. It's an obvious direction once you read it. Well done, and thank you!
Gravatar # re: Android - Create a custom multi-line ListView bound to an ArrayList
by Marcinkonys at 1/19/2012 6:34 PM

Works flawlessly, thank you very much!
Gravatar # String-Array Implementation
by DRAN at 1/26/2012 12:18 PM

I have used this in my code. I have a string-array in my res/values/strings.xml file. How would I use this array in the GetSearchResults()? Thank You.
Gravatar # re: Android - Create a custom multi-line ListView bound to an ArrayList
by RogerThat at 1/28/2012 11:55 AM

I would like to know how to change the text in the list view while the activity is running. Can ANYONE please help me? Thank You.
Gravatar # re: Android - Create a custom multi-line ListView bound to an ArrayList
by Carmen at 2/2/2012 9:03 AM

me parece muy bueno el ejercicio tutorial y muy bien explicado ... gracias .. veamos como me va .. el nombre SearchResults no es muy intiutivo pero es un gran onstructor ...
Gravatar # re: Android - Create a custom multi-line ListView bound to an ArrayList
by shefali chopkar at 2/4/2012 11:40 PM

This is far more better than Android.developer.com\apidemos
Gravatar # re: Android - Create a custom multi-line ListView bound to an ArrayList
by Mike at 2/15/2012 6:35 PM

YOU SAVED MY DAY!!!!!!!!

really good tutorial. the best i found on web
Gravatar # re: Android - Create a custom multi-line ListView bound to an ArrayList
by GOGO at 2/17/2012 3:36 PM

I can not understand that java developers constantly puts examples that are not working. One advice: nex time you put a example, please write ALL CODE (that includes all imports for example). That's the one of the differences between MS.NET and java developers. This example does not work for me. I dont know how to solve problem if ListViewBlogPost function is not declared.
Gravatar # re: Android - Create a custom multi-line ListView bound to an ArrayList
by Kishan at 2/21/2012 8:13 AM

Nice tutorial :) I have used it but its not completely working for me. Suppose that the list view contain 10 items and only 6 are displayed on the mobile screen. For the remaining items, i have to scroll down. But when i check the childCount for listview, it says only 6(the no.of items displayed before scrolling down). When i scroll down and click on those items, the app crashes giving a null pointer exception. Could u help me?
Gravatar # re: Android - Create a custom multi-line ListView bound to an ArrayList
by Girish at 2/27/2012 4:40 AM

Hey, thanks for good article
Gravatar # re: Android - Create a custom multi-line ListView bound to an ArrayList
by hi at 3/2/2012 8:44 AM

@GOGO
"please write ALL CODE (that includes all imports for example)"
-if you have problems with what to import try ctrl+O (letter 'O') all the needed imports for the project would be imported by the class :D
Gravatar # re: Android - Create a custom multi-line ListView bound to an ArrayList
by AndrewT at 3/7/2012 4:55 PM

Instead of getting the data from SearchResult(), how can I adapt this to use string data from strings.xml?
Gravatar # re: Android - Create a custom multi-line ListView bound to an ArrayList
by Kushagra at 3/16/2012 6:40 PM

Very nice tutorial...Explains much about how to implement custom adapter..
Gravatar # re: Android - Create a custom multi-line ListView bound to an ArrayList
by Gyocol at 3/21/2012 2:36 AM

Thanks! Really helpfull tutorial :)
Gravatar # Android:How to create a listview with pictures dynamically?
by Guest at 5/8/2012 12:45 AM

Have being looking for this code since a long time.Please let me know how to create a listview with pictures dynamically?
Gravatar # re: Android - Create a custom multi-line ListView bound to an ArrayList
by red at 5/24/2012 9:32 PM

hey,nice tutorial you got there..I understand every bit.. can i ask question here? I want to put xml parsed data inside arraylist then use this listview to display it..do you know how to do this??I'm using DOMparser here. I can't figure how to pupolate the arraylist in that parser, Thanks for the reply in advance..
Gravatar # re: Android - Create a custom multi-line ListView bound to an ArrayList
by Nissan at 7/2/2012 1:03 AM

Thank you Very Much...:D
Gravatar # re: Android - Create a custom multi-line ListView bound to an ArrayList
by gunloc at 12/5/2012 11:33 PM

nice tutorial thank you
Gravatar # re: Android - Create a custom multi-line ListView bound to an ArrayList
by S@B at 12/13/2012 5:13 PM

i love this... An example that actually works! thnx
Gravatar # re: Android - Create a custom multi-line ListView bound to an ArrayList
by Patrick at 1/29/2013 10:17 AM

It is ok, but you can if you'll create a constructor for the SearchResults Object. You fill the objects at the moment with standard setter methods.
You can initialize the attributes in a constructor too.

Example: (With defaulName)
public SearchResults(String name = "DefaultName", String city, String phone){
this.name = name;
this.city = city;
this.phone = phone;

}

Searchresult s1 = new Searchresults("Name","City","1231231");
Gravatar # re: Android - Create a custom multi-line ListView bound to an ArrayList
by Bill at 1/29/2013 1:38 PM

True, there are probably other/better ways of gettings the data... I was more concerned with showing how to populate the ListView rather than get the data...
Gravatar # re: Android - Create a custom multi-line ListView bound to an ArrayList
by eldr at 2/10/2013 9:25 PM

Thank you for this wonderful post.
Gravatar # re: Android - Create a custom multi-line ListView bound to an ArrayList
by pdr at 2/13/2013 12:27 PM

Hi,

First, thanks for the great post. Like many of the other commenter's, I'm just getting started in Android dev. My question is around the use of the "static" keyword for the list of results as well as the ViewHolder classes. Why are these "static"? Shouldn't they be instance members of the Adapter class?
Gravatar # re: Android - Create a custom multi-line ListView bound to an ArrayList
by Zoha at 5/28/2013 9:52 AM

Nice tutorial, but I am trying to implement different listviews in different tabs. When I run the code blank screen appears for the tab not the listview? Can anybody help ?? Please
Gravatar # re: Android - Create a custom multi-line ListView bound to an ArrayList
by roy at 11/15/2013 2:09 PM

great post ever
Gravatar # re: Android - Create a custom multi-line ListView bound to an ArrayList
by Romanov at 4/6/2014 5:48 AM

nice tutorial, thx man :D
Gravatar # re: Android - Create a custom multi-line ListView bound to an ArrayList
by Carl at 6/3/2014 5:17 AM

I'm trying to use this in a Tabbed Fragment, and am having absolutely no luck changing "extends Activity" to "extends Fragment"

HELP!!!!!

Hoping you have an example of this working with fragments.

Post A Comment
Title:
Name:
Email:
Comment:
Verification: