I am just getting started with the Android SDK and I had a quick question. I am trying to set up a ListView with a rectangle of color on the left and then a bit of text for each row. I also want to make it so I can click each entry in the list and open a new activity to display some information (similar to the contact list). Anyone have any examples to help me out?
Here is an excerpt from one of my books that discusses having complex list rows, like the one you are describing.
If you're looking to avoid subclassing BaseAdapter but want to work with custom item views and custom item click logic based on an object, here's what I did.
In my code I'm working with a collection of some model object. I want to display this collection of model objects in a ListView. I can't just pass an ArrayList of ModelObjects into a SimpleAdapter because it is expecting a List of key-value pairs (Something like List<Map<String, Object>>
). So, instead of using a simple collection of my object within my application, I created a custom class to represent my collection which simply derives from the structure I was using. This way, I can continue to use it as I was, but I can add a method that transforms it from a code-friendly collection into a SimpleAdapter-friendly collection. In my case I was using a HashMap keyed by some string property (ie. HashMap<String, ModelObject>
). My custom collection class would be ModelObjects
(plural) extends HashMap<String, ModelObject>
. ModelObjects
would then contain a ToList()
method where I transform my objects into ArrayList<? extends HashMap<String, ?>>
which I could then pass to the SimpleAdapter constructor to display it in a list with a custom view.
So now I can construct a SimpleAdapter with the following five parameters:
- The context of my list (in my case, the containing Activity)
- My list (described above)
- The id of my custom layout for these items (R.layout.custom_list_item)
- A string array of property names. These are the keys in the HashMap from my ToList method.
- An int array that maps the properties of each item in the above (#4) to a View-derived element id in my custom layout
Then, in my OnItemClickListener.onItemClick method, I can use arg3 to get the position of the item in my list that was clicked and use this to pick out the object from my collection. You can act on any properties of your item or do a big switch/case on some property of your object to launch a particular activity or something like that.
The only trick is that you need to store a local copy of your collection within the activity that doesn't get modified. Otherwise you might be looking up an object by id in the onItemClick and getting a different object than what you'd expect. It may be a little out of context, but here's what my code looks like:
ListView lvArtists = (ListView)findViewById(R.id.lvArtists);
SimpleAdapter adapter = new SimpleAdapter(
this,
artists.ToList(),
R.layout.artist_list_item,
new String[] { "name", "imageIdSmall", "tracksCount", "tracksPending" },
new int[] { R.id.artistListItemName, R.id.artistListItemImage, R.id.artistListItemAudioClips, R.id.artistListItemAudioClipsPending }
);
lvArtists.setAdapter(adapter);
lvArtists.setOnItemClickListener(new OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> arg0, View arg1, int arg2,
long arg3) {
Artist artist = artists.getSortedItem((int)arg3);
mArtistDialog.setArtist(artist);
mArtistDialog.show();
}
});