How to use custom views in ListViews or ListActivities in our Android Programming Environment

Article by Jbeer (2,729 pts )
Edited & published by James Allen Johnson (38,711 pts ) on Nov 18, 2009

In this article we will see how to use a custom view (you create in xml) and use it as a row in a listview.

Introduction

I have been working with listviews and ListActivities from the beginning (Aabout using listview or ListActivities...Whats the difference? Is one better than other? I have to write about this). First of all, I created simple lists, using Arrays (in a very similar way to how we create Spinners), a list with just a text. Then I needed more complex rows in my applications, rows with images, rows with a complex composition of texts, images, backgrounds...So how can this be accomplished?

First of all lets understand how a list is created using a custom BaseAdapter.

In the Android developers page, we can find the following definition of BaseAdapter:

Common base class of common implementation for an Adapter that can be used in both ListView (by implementing the specialized ListAdapter interface} and Spinner (by implementing the specialized SpinnerAdapter interface.

So, using a Base Adapter we can implement ListViews and Spinners. Lets focus in on ListViews.

Custom BaseAdapter

One of the most interesting things using this Base Adapter is that you can implement a list of everything you need. Le'ts use an example. Imagine that we are working in a Twitter application. Our application has a list of tweets, with the avatar, the name of the user, the tweet itself etc... so, lets suppose we have a class “Tweet”, this class “Tweet” then has the following fields:

String tweet

String userName

Date tweetSend

Bitmap imageAvatar

So, this is the information we want to show in every row in the list.

Lets compose our main Activity.

Here we have:

List<Tweet> tweetList;

(We fill this list from a database we have, from information in the Internet, etc...)

In our Activity (We are using a Activity not a ListActivity!!) we get the “listview” element we should have in our XML. (Remember, every Activity has an XML file associated with it)

Then, we have to call this method:

TweetRowAdapter adapter = new TweetRowAdapter(this, tweetList);

(The list must be fill with data!!)

The TweeetRowAdapter class is a class created by ourselves, this class extends BaseAdapter:

public class TweeetRowAdapter extends BaseAdapter {

This class have some methods that have to be implemented:

public int getCount()

public Object getItem(int position)

public long getItemId(int position)

And the MOST important:

public View getView(int position, View convertView, ViewGroup parent)

The way to implement the 3 first methods is almost the same in all BaseAdapters:

public int getCount() {

return elements.size();

}

public Object getItem(int position) {

return elements.get(position);

}

public long getItemId(int position) {

return position;

}

Not very complex.

We need to create a constructor to call it from outside, passing a List of Tweets as parameters.

private List<Tweets> elements;

public TweeetRowAdapter(Context mContext, List<Tweet> elements) {

this.mContext = mContext;

this.elements = elements;

}

Now we have the list of tweets inside the Base Adapter. Now let's continue creating a custom View.

Creating a custom View

This part is easy. Just create a xml view, with the structure, elements (Images, TextViews, Buttons...) you want.

Once we have our xml (our is called, for example, “row_tweet.xml”) we can go to the next step.

Attaching the view to the list.

And this final part is the most interesting!

Remember what I said about the getView method in the TweetRowAdapter? I said that this method is the most important. Let's see why.

We start the method as follows:

public View getView(int position, View convertView, ViewGroup parent) {

RelativeLayout rowLayout;

final Tweet tweet = elements.get(position);

if (convertView == null) {

rowLayout = (RelativeLayout) LayoutInflater.from(mContext).inflate(R.layout.row_tweet, parent, false);

} else {

rowLayout = (RelativeLayout) convertView;

}

The most important part is the LayoutInflater method. Its like “use the layout you have in the xml file to create a row”.

I have put a “RelativeLayout” as rowLayout, but this depends on what you have in your custom view as root element. Do you have a linearLayout? Then put LinearLayout instead of Relativelayout in the code above.

Then, in the rowLayout we have a full layout... now we can get and edit its elements:

TextView nameUser = (TextView) rowLayout.findViewById(R.id.tweet_user_name);

(Imagine that you have a TextView in the row_tweet.xml file that have the "id" as "twee_user_name")

editing!

nameUser.setText(tweet.getUserName())

tweet is every row in the list. (Remember Tweet class? We have it here)

And don't forget to return the view!

return rowLayout

Follow up

If you want to know when new articles are released, subscribe yourselft to the Google Android RSS Otherwise, you can follow my research, articles and work in my profesional twitter: jbeerdev

Comments

Feb 11, 2010 9:55 AM
RE: How to use custom views in ListViews or ListActivities in our Android Programming Environment
Hi!
Well, here in Bright Hub there are lots of good articles about android, and if you want to go deeper, you can visit the Android developers Page:

http://developer.android.com/index.html

Here some of my articles:

http://sites.google.com/site/josebcortes/articulos/the-bright-hub
Feb 11, 2010 9:01 AM
help
I need some Material for Android
Jan 29, 2010 2:30 AM
RE: How to use custom views in ListViews or ListActivities in our Android Programming Environment
I see the point, David.

I dont know if the way I do it its the best way, but it works :)

In the "row_tweet.xml" file, Imagine that there is just a LinearLayout, a TextView and a Button. In the elements you want to interact with, put a
android:focusable="true" android:clickable="true"

Inside the Adapter, you place the Listeners associated to that elements.
I think nothing is missing, thats its how I use them. Anyway, I will expand this article to add this.
Thanks for the point, david.
Jan 28, 2010 2:33 PM
David Phillip Oster
Yes, but is it tappable?
I'm doing essentially the same thing you describe, but when I tap on a table item, the item doesn't highlight, and when I use the trackball, the Adapter's onItemClick is never called.

Can you go into detail on your row_tweet.xml ?

Can you go into detail on the onItemClick of your adapter?

As it stands, this article describes how to display the items of a list, but not how the user can actually do anything with it.
Jan 28, 2010 3:04 AM
RE: How to use custom views in ListViews or ListActivities in our Android Programming Environment
Hi David

This like is the way of saying:

"This is the element (in this case a textview) from the layout I use to show my row (in this case the rowLayout object)"

The Textview I have there, must be declared inside the xml you use to "inflate" your layout.

rowLayout = (RelativeLayout) LayoutInflater.from(mContext).inflate(R.layout.row_tweet, parent, false);

it must be in the "row_tweet" xml file.

And the full source code is there, I mean, splitted, but the full functionality is using the code above.
Jan 27, 2010 3:38 PM
David
full code
hi
please can you provide the full code of this excelent example?
or at least this line to wich function it belows
TextView nameUser = (TextView) rowLayout.findViewById(R.id.tweet_user_name);
thanks