Customizing Views with ListViews or ListActivities

Written by:  • Edited by: Simon Hill
Updated May 3, 2011
• Related Guides: Android | Google

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.\

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 yourself to the Google Android RSS Otherwise, you can follow my research, articles and work in my profesional twitter: jbeerdev

Comments

Showing all 12 comments
 
Lee Nov 26, 2011 9:31 AM
RE: Customizing Views with ListViews or ListActivities
The perfect tutorial, not the whole source (so no lazy copy/paste) but just enough to make you realise how easy it is and keep your brain thinking while you work through it.  Brilliant, thanks muchlee
rohan Feb 3, 2011 5:52 AM
populate list
Could you please explain how to populate the tweetList with tweet objects.. I can't find the syntax!

Thanks!
rohan Feb 3, 2011 5:25 AM
fill tweetList
hi,
could u please explain how to fill the tweetList.. I can't find the syntax for adding elements(tweet objects) to the list..
thanks!
anki Dec 29, 2010 3:56 AM
full code please
please provide the full source code for this
chris Nov 13, 2010 12:48 PM
You are just the best
Just the thing i needed, thanks.
renuka Aug 2, 2010 2:40 AM
excellent tutorial
but we need full explanation along with twitter libs
Jbeerdev Feb 11, 2010 9:55 AM
RE: Customizing Views with ListViews or ListActivities
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
brijesh Feb 11, 2010 9:01 AM
help
I need some Material for Android
Jbeerdev Jan 29, 2010 2:30 AM
RE: Customizing Views with ListViews or ListActivities
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.
David Phillip Oster Jan 28, 2010 2:33 PM
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.
Jbeerdev Jan 28, 2010 3:04 AM
RE: Customizing Views with ListViews or ListActivities
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.
David Jan 27, 2010 3:38 PM
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
 
blog comments powered by Disqus
Email to a friend