One of the most common interface elements used in Android apps is the ListView. This presents to the user a scrollable list of tappable items. The best place to start with this is and Android Developers ListView Tutorial which will cover the basics of creating an activity with the ListView control and displaying a list of items from a string array.
In a real world app you will probably want to build a list with something other than a string array. Commonly you will have a collection of your own type of object, or you may want to display listview items with an icon. I will show you how to use a ListView to display these objects and also handle the tap event.
Let's start with the class object that will consist of a text label, a drawable for the icon and also an index value to track item selection:
CustomListItem.java
Now that we have our class defined, let's create the layout that will be used to display the individual list item, which is a simple RelativeView with an ImageView for the icon and a TextView for the label:package com.example.advancedList; import android.graphics.drawable.Drawable; public class CustomListItem { private int mIndex; private String mLabel; private Drawable mPicture; public CustomListItem(final int index, final String label, final Drawable pic) { mIndex = index; mLabel = label; mPicture = pic; } public int getIndex() { return mIndex; } public String getLabel() { return mLabel; } public Drawable getPicture() { return mPicture; } }
Create res/layout/list_item.xml :
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="fill_parent"> <TextView android:id="@+id/txtLabel" android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="List item" /> <ImageView android:id="@+id/txtImgIcon" android:layout_width="wrap_content" android:layout_height="wrap_content" android:src="@null" android:layout_toRightOf="@id/txtLabel" /> </RelativeLayout>
Hopefully so far everything has been quite straight forward. We now need to define a custom list adapter that extends the BaseAdapter class, this will allow us to fully control the way the ListView is constructed.
Create a class named MyListItemAdapter.java:
package com.example.advancedList; import java.util.List; import android.content.Context; import android.graphics.Bitmap; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.BaseAdapter; import android.widget.ImageView; import android.widget.RelativeLayout; import android.widget.TextView; // Custom list item class for menu items public class MyListItemAdapter extends BaseAdapter { private List<CustomListItem> items; private Context context; private int numItems = 0; public MyListItemAdapter(final List<CustomListItem> items, Context context) { this.items = items; this.context = context; this.numItems = items.size(); } public int getCount() { return numItems; } public CustomListItem getItem(int position) { return items.get(position); } public long getItemId(int position) { return 0; } public View getView(int position, View convertView, ViewGroup parent) { // Get the current list item final CustomListItem item = items.get(position); // Get the layout for the list item final RelativeLayout itemLayout = (RelativeLayout) LayoutInflater.from(context).inflate(R.layout.list_item, parent, false); // Set the icon as defined in our list item ImageView imgIcon = (ImageView) itemLayout.findViewById(R.id.imgIcon); imgIcon.setImageDrawable(item.getPicture()); // Set the text label as defined in our list item TextView txtLabel = (TextView) itemLayout.findViewById(R.id.txtLabel); txtLabel.setText(item.getLabel()); return itemLayout; } }
We'll call the file res/layout/list_example.xml :
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_height="fill_parent" android:layout_width="fill_parent"> <ListView android:id="@id/android:list" android:layout_height="wrap_content" android:layout_width="fill_parent" /> <TextView android:id="@id/android:empty" android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="Nothing to list" /> </LinearLayout>
We now need to build our main Activity which extends the ListActivity class using our layout defined previously. Within the activity's onCreate method we create a List of our CustomListItem type and add 3 new items to it. We then populate a new ListAdapter using our myListItemAdapter class and assign to it our list of items:
src/com.example.advancedList/Main.java :
package com.example.advancedList; import java.util.ArrayList; import java.util.List; import android.app.ListActivity; import android.os.Bundle; import android.view.View; import android.widget.AdapterView; import android.widget.ListAdapter; import android.widget.ListView; import android.widget.AdapterView.OnItemClickListener; public class Main extends ListActivity { @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.list_example); // Create list of items based upon class final List<CustomListItem> items = new ArrayList<CustomListItem>(3); items.add(new CustomListItem (1, "Item 1", getResources().getDrawable(R.drawable.icon))); items.add(new CustomListItem (2, "Item 2", getResources().getDrawable(R.drawable.icon))); items.add(new CustomListItem (3, "Item 3", getResources().getDrawable(R.drawable.icon))); // Populate the list view ListAdapter adapter = new myListItemAdapter(items, this); ListView lv = getListView(); // Because we are extending ListActivity we cal this but could specify lv.setAdapter(adapter); lv.setTextFilterEnabled(true); // Add listener for item clicks lv.setOnItemClickListener(new OnItemClickListener() { public void onItemClick(AdapterView<?> parent, View view, int position, long id) { // Retrieve our class object and use index to resolve item tapped final MenuListItem item = items.get(position); final int menuIndex = item.getIndex(); switch (menuIndex) { case 1: break; case 2: break; case 3: break; default: break; } } }); } }
You'll see that once we have our list adapter set up it is applied to the list view. We then assign a listener to the list view to pick up click events. Within this the first thing we do it obtain the item from the list that was clicked. We then have the freedom to make our code react to any aspect of our object.
I have used this approach several times and in fact have never displayed a list from a string array. I hope you find this guide useful.
4 comments:
thx it helps me...
thank you
have been looking all day for something like trhat, thisone works out of the box.
Just 2 naming issues:
CustomListItem becomes MenuListItem
and
txtImgIcon becomes imgIcon
otherwise it works thank you !!!
Custom ListView control
ListView item class object
Post a Comment