Tutorial: Custom ListView with ImageViews and TextViews

There is no doubt that the ListView is one of the most used Android UI components, in most cases developers find themselves in a situation where they need to customize this component, instead of just showing a list of Strings on the screen they also need to show more information, an ImageView, or even a Button.

In this tutorial I’m going to show how easy it is to customize a ListView, I’ll create a Contact List app with a customized ListView that will display the contacts, instead of just showing the name it’ll also show the phone number and the picture, the result will be like the customized ListView in the image bellow:

Customized ListView
Standard ListView x Customized ListView

As you can see in the image, we’re going to use 2 TextViews and 1 ImageView in this list, so let’s start by creating our ListView component, when we create the Android project it already comes with an activity_main.xml file, that’s where we’re going to add our ListView code.

1
2
3
4
5
6
7
8
9
10
11
12
13
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent"
    android:layout_height="match_parent" android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    android:paddingBottom="@dimen/activity_vertical_margin" tools:context=".MainActivity">
 
    <ListView
        android:id="@+id/list"
        android:layout_height="wrap_content"
        android:layout_width="match_parent">
    </ListView>
</RelativeLayout>

There’s really nothing special here, we’ve just created the ListView and gave the id “list” to it, you could give any id you want, but you should remember it, we are going to use it later.

The next step is to create another xml file that will be our custom layout, let’s call it contactlist.xml, it should look like this:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="horizontal" >
    <ImageView
        android:src="@drawable/person"
        android:layout_width="@dimen/picture_width"
        android:layout_height="@dimen/picture_height" />
 
    <LinearLayout
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:orientation="vertical">
        <TextView
            android:id="@+id/contactName"
            android:layout_marginLeft="@dimen/margin"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:paddingTop="5dp"/>
 
        <TextView
            android:id="@+id/contactPhone"
            android:layout_marginLeft="@dimen/margin"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:paddingTop="5dp"/>
    </LinearLayout>
</LinearLayout>

It’s just like the first one, but with a few more things, this is the layout that is going to be used to display each of ListView items, you can add as many components as you want to this file, but in this example I’ll keep it simple and use just an ImageView and two TextViews like I said before. Don’t forget to give an id to each component. You’ll also need an image to be displayed on the ImageView, pick one of your preference and put it on the drawable folder, them you should be able reference it in the ImageView src attribute.

Now that our views are done, we can go on and start writing some Java code, the first class we need to create is the Contact.java, it’ll only contain the name and phone attributes.

1
2
3
4
5
6
7
8
9
10
11
12
public class Contact {
 
    private String name;
    private String phone;
 
    public Contact(String name, String phone) {
        this.name = name;
        this.phone = phone;
    }
 
    //GETTERS AND SETTERS
}

Really simple, there’s not much to explain here, all of you should already be familiar with Java.

Now we’re going to create our Adapter, this will be the class responsible for getting the data from our List and putting it into our UI components, let’s call it “ContactsAdapter”:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
public class ContactsAdapter extends ArrayAdapter<Contact>{
 
    int resource;
    String response;
    Context context;
 
    public ContactsAdapter(Context context, int resource, List<Contact> items) {
        super(context, resource, items);
        this.resource=resource;
    }
 
    @Override
    public View getView(int position, View convertView, ViewGroup parent)
    {
        LinearLayout contactsView;
        Contact contact = getItem(position);
        if(convertView==null) {
            contactsView = new LinearLayout(getContext());
            String inflater = Context.LAYOUT_INFLATER_SERVICE;
            LayoutInflater vi;
            vi = (LayoutInflater)getContext().getSystemService(inflater);
            vi.inflate(resource, contactsView, true);
        } else {
            contactsView = (LinearLayout) convertView;
        }
        TextView contactName =(TextView)contactsView.findViewById(R.id.contactName);
        contactName.setTypeface(null, Typeface.BOLD);
        contactName.setTextSize(TypedValue.COMPLEX_UNIT_PX,18);
        TextView contactPhone = (TextView)contactsView.findViewById(R.id.contactPhone);
        contactPhone.setTextSize(TypedValue.COMPLEX_UNIT_PX,14);
        contactName.setText(contact.getName());
        contactPhone.setText(contact.getPhone());
        return contactsView;
    }
}

This is a little bit more complicated, there’s quite a lot of things happening here, first note that I’m extending the class ArrayAdapter, we must do this, otherwise our application won’t recognize it as an adapter. Now let’s take a look at the getView method, in the lines 26 and 29 we’re getting the two TextViews from the contactlist.xml by its ids, at this moment we can modify every attribute of these components, as an example I modified the textSize in the lines 28 and 30 and also the typeface in the line 27. But the most important thing in this method is happening on the lines 31 and 32, that’s where I got the values “name” and “phone” from my Contact and passed them to my TextView objects.

Ok, now that we have an Adapter we should be able to write the code that will tie everything together, let’s open our MainActivity.java, we’re only going to modify the onCreate method:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
    ListView listView;
 
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
 
        List<Contact> contacts = new ArrayList<Contact>();
        contacts.add(new Contact("Gloria Miller","86-(216)605-9056"));
        contacts.add(new Contact("Teresa Garrett","86-(131)666-7051"));
        contacts.add(new Contact("Jeremy Diaz","370-(899)196-6943"));
        contacts.add(new Contact("Rose Henry","420-(240)605-2163"));
        contacts.add(new Contact("Maria Kelly","62-(488)190-3222"));
 
        listView = (ListView) findViewById(R.id.list);
        ContactsAdapter adapter = new ContactsAdapter(this,
                R.layout.contactlist, contacts);
        listView.setAdapter(adapter);
    }

In this method I’m creating the contact list and adding each item to it, in this case I’ve hard-coded the data in this class, but in a real scenario it would have come from a database or a web service. Next we need to get our ListView, we’re going to get it by its id, exactly like we did before with the TextViews, and the last step is to instantiate our Adater, its constructor will receive our contactlist.xml and the data as parameters.

That’s it! Now if you run your app the result should be exactly like the image in the beginning of the post.

Recommended for you

Leave a Reply

Your email address will not be published. Required fields are marked *

Obs: Use the tag <pre lang="LANGUAGE"> to include code blocks to your comment.
Example: <pre lang="javascript"> console.log('Test'); </pre>