List View is an element that displays a collection of items in single column direction. It has an internal vertical scroll bar that enable user to scroll if it’s height bigger than display height. The type of single item in the list is any of java object.
[cci]ListView[/cci] needs an adapter to works. This adapter behaves as a data resources for the list. The adapter also defines how each items in the list is displayed. The adapter is attached to the list via [cci]setAdapter[/cci] method on the [cci]ListView[/cci] object. There are two commons used adapters:
- Array Adapter: An adapter that is designed to work with arrays data resources.
- Cursor Adapter: An adapter that is designed to handle database related data.
This tutorial will focuses on array adapter.
Simple Array Adapter
A simple array adapter is an array adapter that is built using array of string as items. The array of string is passed to the constructor of [cci]ArrayAdapter[/cci] object.
List<String> apps = new ArrayList<String>(); apps.add("Twitter"); apps.add("Whatsapp"); apps.add("Facebook"); ArrayAdapter<String> adapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, apps);
The constructor of array adapter have 3 arguments:
- context: this is the application context
- layout resource id: the layout resource id for item view
- array items: this is array object for items
We will attach the created adapter into the list by using [cci]setAdapter[/cci] method on [cci]ListView[/cci] object.
List Activity
[cci]ListActivity[/cci] is a subclass of [cci]Activity[/cci] that will make our work with [cci]ListView[/cci] easier. [cci]ListActivity[/cci] has internal implementation method that is related to [cci]ListView[/cci]. You must have list view object with id is [cci]android:id/list[/cci] in the layout file to use List Activity.
<ListView android:id="@android:id/list" android:layout_width="match_parent" android:layout_height="wrap_content" > </ListView>
Now we will create a sample list view application using simple array adapter. Open your Eclipse IDE and create new android project by selecting menu: File -> New -> Android Application Project. Fill out required fields.
- Create new xml file: [cci]activity_main.xml[/cci]
<LinearLayout 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" > <ListView android:id="@android:id/list" android:layout_width="match_parent" android:layout_height="wrap_content"> </ListView> </LinearLayout>
- Create new activity class: [cci]MainActivity.java[/cci]
package com.sj.customlistview; import java.util.ArrayList; import java.util.List; import android.app.ListActivity; import android.os.Bundle; import android.widget.ArrayAdapter; public class MainActivity extends ListActivity{ @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); initView(); } private void initView() { List<String> apps = new ArrayList<String>(); apps.add("Twitter"); apps.add("Whatsapp"); apps.add("Facebook"); ArrayAdapter<String> adapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, apps); setListAdapter(adapter); } }
- Put your activity in [cci]AndroidManifest.xml[/cci] file
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.sj.customlistview" android:versionCode="1" android:versionName="1.0" > <uses-sdk android:minSdkVersion="8" android:targetSdkVersion="17" /> <application android:allowBackup="true" android:icon="@drawable/ic_launcher" android:label="@string/app_name" android:theme="@style/AppTheme" > <activity android:name="com.sj.customlistview.MainActivity" android:label="@string/app_name" > <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> </application> </manifest>
Run your project, your list view will be displayed like image below:
Customize Array Adapter
By default, array adapter displays a [cci]TextView[/cci] for each items and set the text of it by calling [cci]toString[/cci] method of item object. We can customize the default display of array adapter by overriding [cci]getView[/cci] method.
For a demo, we will modify previous project and use custom array adapter:
- Create new java class: [cci]Application.java[/cci].
This class represents a single object of list item.package com.sj.customlistview; public class Application { private String title; private long totalDl; private int rating; private String icon; public String getTitle() { return title; } public void setTitle(String title) { this.title = title; } public long getTotalDl() { return totalDl; } public void setTotalDl(long totalDl) { this.totalDl = totalDl; } public int getRating() { return rating; } public void setRating(int rating) { this.rating = rating; } public String getIcon() { return icon; } public void setIcon(String icon) { this.icon = icon; } }
- Create new xml file: [cci]app_custom_list.xml[/cci]
This file defines a view for list item<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" > <ImageView android:id="@+id/appIcon" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentLeft="true" android:layout_alignParentTop="true" android:layout_marginLeft="3dp" android:layout_marginTop="3dp" android:src="@drawable/facebook" /> <TextView android:id="@+id/titleTxt" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignTop="@id/appIcon" android:layout_toRightOf="@id/appIcon" android:layout_marginLeft="3dp" android:text="Application Title" android:textSize="22dp"/> <LinearLayout android:id="@+id/ratingCntr" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_toRightOf="@id/appIcon" android:layout_below="@id/titleTxt" android:layout_marginLeft="5dp" > </LinearLayout> <TextView android:id="@+id/dlTxt" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_below="@id/titleTxt" android:layout_alignParentRight="true" android:layout_marginRight="3dp" android:text="0 dl" /> </RelativeLayout>
- Create new java class: [cci]AppAdapter.java[/cci]
This is our adapter that will inflate [cci]app_custom_list.xml[/cci] and set the data into it.package com.sj.customlistview; import java.text.NumberFormat; import java.util.List; import android.content.Context; import android.content.res.Resources; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.ArrayAdapter; import android.widget.ImageView; import android.widget.LinearLayout; import android.widget.TextView; public class AppAdapter extends ArrayAdapter<Application>{ private List<Application> items; public AppAdapter(Context context, List<Application> items) { super(context, R.layout.app_custom_list, items); this.items = items; } @Override public int getCount() { return items.size(); } @Override public View getView(int position, View convertView, ViewGroup parent) { View v = convertView; if(v == null) { LayoutInflater li = LayoutInflater.from(getContext()); v = li.inflate(R.layout.app_custom_list, null); } Application app = items.get(position); if(app != null) { ImageView icon = (ImageView)v.findViewById(R.id.appIcon); TextView titleText = (TextView)v.findViewById(R.id.titleTxt); LinearLayout ratingCntr = (LinearLayout)v.findViewById(R.id.ratingCntr); TextView dlText = (TextView)v.findViewById(R.id.dlTxt); if(icon != null) { Resources res = getContext().getResources(); String sIcon = "com.sj.customlistview:drawable/" + app.getIcon(); icon.setImageDrawable(res.getDrawable(res.getIdentifier(sIcon, null, null))); } if(titleText != null) titleText.setText(app.getTitle()); if(dlText != null) { NumberFormat nf = NumberFormat.getNumberInstance(); dlText.setText(nf.format(app.getTotalDl())+" dl"); } if(ratingCntr != null && ratingCntr.getChildCount() == 0) { /* * max rating: 5 */ for(int i=1; i<=5; i++) { ImageView iv = new ImageView(getContext()); if(i <= app.getRating()) { iv.setImageDrawable(getContext().getResources().getDrawable(R.drawable.start_checked)); } else { iv.setImageDrawable(getContext().getResources().getDrawable(R.drawable.start_unchecked)); } ratingCntr.addView(iv); } } } return v; } }
- Open your [cci]MainActivity.java[/cci] and modify several lines.
package com.sj.customlistview; import java.util.ArrayList; import java.util.List; import android.app.ListActivity; import android.os.Bundle; public class MainActivity extends ListActivity{ @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); initView(); } private void initView() { List<Application> apps = populateSampleApplication(); AppAdapter adapter = new AppAdapter(this, apps); setListAdapter(adapter); } private List<Application> populateSampleApplication(){ String[] apps = new String[] { "Twitter,450000,5,twitter", "Skype,300002,2,skype", "Facebook,500560,4,facebook" }; List<Application> list = new ArrayList<Application>(); for(String app:apps) { String[] rApp = app.split(","); Application ap = new Application(); ap.setTitle(rApp[0]); ap.setTotalDl(Integer.parseInt(rApp[1])); ap.setRating(Integer.parseInt(rApp[2])); ap.setIcon(rApp[3]); list.add(ap); } return list; } }
I’ve used some social icons in this project. You can download the icons here: social icons
Now run your project, it will display list view below: