Geeks With Blogs
Bill Osuch - Random geek notes

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:

Posted on Monday, January 31, 2011 3:33 PM | Back to top


Comments on this post: Android - Create a custom multi-line ListView bound to an ArrayList

# re: Android - Create a custom multi-line ListView bound to an ArrayList
Requesting Gravatar...
Thank you! Been looking all over for this! :)
Left by hyunjungsoh on Feb 06, 2011 5:47 PM

# re: Android - Create a custom multi-line ListView bound to an ArrayList
Requesting Gravatar...
I've found many tutorial with same the subject, but I think this one I can "follow" easily. Thx man, you rocks!
Left by Sigit on Feb 12, 2011 2:30 PM

# re: Android - Create a custom multi-line ListView bound to an ArrayList
Requesting Gravatar...
Excelent article. Thanks
Left by vicman on Mar 17, 2011 10:21 AM

# re: Android - Create a custom multi-line ListView bound to an ArrayList
Requesting Gravatar...
comment faire pour avoir une Listview aved différente ligne....
Left by Firas ayed on Apr 04, 2011 3:14 PM

# re: Android - Create a custom multi-line ListView bound to an ArrayList
Requesting Gravatar...
Great work .....
Its so simple and easy in understanding
Left by subktageen on Apr 08, 2011 12:49 PM

# re: Android - Create a custom multi-line ListView bound to an ArrayList
Requesting Gravatar...
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?
Left by Stefan den Hartog on Jun 22, 2011 1:22 PM

# re: Android - Create a custom multi-line ListView bound to an ArrayList
Requesting Gravatar...
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.
Left by Bill on Jun 23, 2011 9:41 AM

# re: Android - Create a custom multi-line ListView bound to an ArrayList
Requesting Gravatar...
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.
Left by Renjith on Jul 01, 2011 8:12 AM

# re: Android - Create a custom multi-line ListView bound to an ArrayList
Requesting Gravatar...
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?
Left by nik on Jul 13, 2011 8:49 PM

# re: Android - Create a custom multi-line ListView bound to an ArrayList
Requesting Gravatar...
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?
Left by Bill on Jul 15, 2011 8:28 AM

# re: Android - Create a custom multi-line ListView bound to an ArrayList
Requesting Gravatar...
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.
Left by nik on Jul 17, 2011 12:18 PM

# Searchable List View
Requesting Gravatar...
Nice Tutorial (*!*) so simply explained
How to attach a search dialog,so that we can search list items based on name
Left by RojyGeorge on Aug 23, 2011 3:23 AM

# re: Android - Create a custom multi-line ListView bound to an ArrayList
Requesting Gravatar...
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?
Left by Glenn on Aug 27, 2011 1:37 PM

# re: Android - Create a custom multi-line ListView bound to an ArrayList
Requesting Gravatar...
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 :-)
Left by Rich on Sep 20, 2011 3:06 AM

# re: Android - Create a custom multi-line ListView bound to an ArrayList
Requesting Gravatar...
thanks mate :)
Left by nyom2 on Oct 15, 2011 10:29 AM

# re: Android - Create a custom multi-line ListView bound to an ArrayList
Requesting Gravatar...
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) {
Left by hussainkothari on Oct 18, 2011 4:33 AM

# re: Android - Create a custom multi-line ListView bound to an ArrayList
Requesting Gravatar...
Thank you very much, finally tutorial which showed me doable way.
Left by Josef Halicek on Oct 29, 2011 7:22 PM

# re: Android - Create a custom multi-line ListView bound to an ArrayList
Requesting Gravatar...
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.
Left by Aaron on Nov 14, 2011 5:47 PM

# re: Android - Create a custom multi-line ListView bound to an ArrayList
Requesting Gravatar...
Thank you very much for such a great post. It provides the structured way for binding multiple data items in an ArrayList to ListView.
Left by priya on Nov 29, 2011 12:31 AM

# re: Android - Create a custom multi-line ListView bound to an ArrayList
Requesting Gravatar...
This was nice . psot iw as new in android but from this Example i did 2 application...and now its running in market..
Left by Anil on Dec 12, 2011 5:25 AM

# re: Android - Create a custom multi-line ListView bound to an ArrayList
Requesting Gravatar...
Great post!
Left by Sergio on Dec 18, 2011 9:40 AM

# re: Android - Create a custom multi-line ListView bound to an ArrayList
Requesting Gravatar...
This is really great, thanks a lot!
Left by John mcClane on Jan 06, 2012 1:53 AM

# re: Android - Create a custom multi-line ListView bound to an ArrayList
Requesting Gravatar...
great tuto! But how to add pictures with listview??
Left by daca on Jan 06, 2012 4:03 PM

# re: Android - Create a custom multi-line ListView bound to an ArrayList
Requesting Gravatar...
its very simple and really great tutorial for novice users.
Left by wasif hamdani on Jan 09, 2012 7:23 AM

# re: Android - Create a custom multi-line ListView bound to an ArrayList
Requesting Gravatar...
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();
Left by Nuno Horta on Jan 13, 2012 9:39 AM

# re: Android - Create a custom multi-line ListView bound to an ArrayList
Requesting Gravatar...
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!
Left by Mike on Jan 15, 2012 10:58 PM

# re: Android - Create a custom multi-line ListView bound to an ArrayList
Requesting Gravatar...
Works flawlessly, thank you very much!
Left by Marcinkonys on Jan 19, 2012 6:34 PM

# String-Array Implementation
Requesting Gravatar...
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.
Left by DRAN on Jan 26, 2012 12:18 PM

# re: Android - Create a custom multi-line ListView bound to an ArrayList
Requesting Gravatar...
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.
Left by RogerThat on Jan 28, 2012 11:55 AM

# re: Android - Create a custom multi-line ListView bound to an ArrayList
Requesting Gravatar...
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 ...
Left by Carmen on Feb 02, 2012 9:03 AM

# re: Android - Create a custom multi-line ListView bound to an ArrayList
Requesting Gravatar...
This is far more better than Android.developer.com\apidemos
Left by shefali chopkar on Feb 04, 2012 11:40 PM

# re: Android - Create a custom multi-line ListView bound to an ArrayList
Requesting Gravatar...
YOU SAVED MY DAY!!!!!!!!

really good tutorial. the best i found on web
Left by Mike on Feb 15, 2012 6:35 PM

# re: Android - Create a custom multi-line ListView bound to an ArrayList
Requesting Gravatar...
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.
Left by GOGO on Feb 17, 2012 3:36 PM

# re: Android - Create a custom multi-line ListView bound to an ArrayList
Requesting Gravatar...
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?
Left by Kishan on Feb 21, 2012 8:13 AM

# re: Android - Create a custom multi-line ListView bound to an ArrayList
Requesting Gravatar...
Hey, thanks for good article
Left by Girish on Feb 27, 2012 4:40 AM

# re: Android - Create a custom multi-line ListView bound to an ArrayList
Requesting Gravatar...
@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
Left by hi on Mar 02, 2012 8:44 AM

# re: Android - Create a custom multi-line ListView bound to an ArrayList
Requesting Gravatar...
Instead of getting the data from SearchResult(), how can I adapt this to use string data from strings.xml?
Left by AndrewT on Mar 07, 2012 4:55 PM

# re: Android - Create a custom multi-line ListView bound to an ArrayList
Requesting Gravatar...
Very nice tutorial...Explains much about how to implement custom adapter..
Left by Kushagra on Mar 16, 2012 6:40 PM

# re: Android - Create a custom multi-line ListView bound to an ArrayList
Requesting Gravatar...
Thanks! Really helpfull tutorial :)
Left by Gyocol on Mar 21, 2012 2:36 AM

# Android:How to create a listview with pictures dynamically?
Requesting Gravatar...
Have being looking for this code since a long time.Please let me know how to create a listview with pictures dynamically?
Left by Guest on May 08, 2012 12:45 AM

# re: Android - Create a custom multi-line ListView bound to an ArrayList
Requesting Gravatar...
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..
Left by red on May 24, 2012 9:32 PM

# re: Android - Create a custom multi-line ListView bound to an ArrayList
Requesting Gravatar...
Thank you Very Much...:D
Left by Nissan on Jul 02, 2012 1:03 AM

# re: Android - Create a custom multi-line ListView bound to an ArrayList
Requesting Gravatar...
nice tutorial thank you
Left by gunloc on Dec 05, 2012 11:33 PM

# re: Android - Create a custom multi-line ListView bound to an ArrayList
Requesting Gravatar...
i love this... An example that actually works! thnx
Left by S@B on Dec 13, 2012 5:13 PM

# re: Android - Create a custom multi-line ListView bound to an ArrayList
Requesting Gravatar...
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");
Left by Patrick on Jan 29, 2013 10:17 AM

# re: Android - Create a custom multi-line ListView bound to an ArrayList
Requesting Gravatar...
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...
Left by Bill on Jan 29, 2013 1:38 PM

# re: Android - Create a custom multi-line ListView bound to an ArrayList
Requesting Gravatar...
Thank you for this wonderful post.
Left by eldr on Feb 10, 2013 9:25 PM

# re: Android - Create a custom multi-line ListView bound to an ArrayList
Requesting Gravatar...
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?
Left by pdr on Feb 13, 2013 12:27 PM

# re: Android - Create a custom multi-line ListView bound to an ArrayList
Requesting Gravatar...
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
Left by Zoha on May 28, 2013 9:52 AM

# re: Android - Create a custom multi-line ListView bound to an ArrayList
Requesting Gravatar...
great post ever
Left by roy on Nov 15, 2013 2:09 PM

# re: Android - Create a custom multi-line ListView bound to an ArrayList
Requesting Gravatar...
nice tutorial, thx man :D
Left by Romanov on Apr 06, 2014 5:48 AM

# re: Android - Create a custom multi-line ListView bound to an ArrayList
Requesting Gravatar...
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.

Left by Carl on Jun 03, 2014 5:17 AM

# re: Android - Create a custom multi-line ListView bound to an ArrayList
Requesting Gravatar...
No enclosing instance of type Image_Adapter is accessible. Must qualify the allocation with an enclosing instance of type Image_Adapter (e.g. x.new
A() where x is an instance of Image_Adapter).

Please suggest solution.
Left by Sulaiman Khan on Dec 02, 2014 7:22 AM

# re: Android - Create a custom multi-line ListView bound to an ArrayList
Requesting Gravatar...
I tried the code and it worked fine. Then I tried to add it to an activity with navigational drawer and then I get a blank list. I have done all kinds of test to find out what is wrong but have had no success yet.

Please have you ever ran the code in an activity with navigational drawer? Would love some help

Thank you
Left by Edwin Okugbo on Jan 07, 2015 11:33 AM

# re: Android - Create a custom multi-line ListView bound to an ArrayList
Requesting Gravatar...
Hi! Thanks for the tutorial!

I have a bit of a trouble using this though.

I have two lists in an fragment which are being populated with different data.

I try to do the following

List1.setAdapter(new CustomAdapter(context, list1data));
List2.setAdapter(new CustomAdapter(context, list2data));

It so happens that both the lists are being populated with list2data.

What could be causing this issue? What could be done to rectify it?
Left by Shavya on Feb 21, 2015 4:31 AM

Your comment:
 (will show your gravatar)


Copyright © Bill Osuch | Powered by: GeeksWithBlogs.net | Join free