Tutorials Android How to Create an Android ListView with Section Header

How to Create an Android ListView with Section Header

In this example we will show how to create a ListView with section header. This involves following steps

  1. Create two custom layout for your List header and List row
  2. Create your custom adapter for ListView
  3. Instantiate ListView in your activity

Create Custom layout for List header and List row

snippet_item1.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:gravity="center_vertical" >

    <TextView
        android:id="@+id/text"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:background="#FFF"
        android:gravity="center_vertical"
        android:padding="5dp"
        android:textAppearance="?android:attr/textAppearanceLarge"
        android:textColor="#FF000000" />

</LinearLayout>

snippet_item2.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:background="#2F2F2F"
    android:gravity="center_vertical" >

    <TextView
        android:id="@+id/textSeparator"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:gravity="center"
        android:padding="8dp"
        android:text=""
        android:textAllCaps="true"
        android:textAppearance="?android:attr/textAppearanceLarge"
        android:textColor="#FFF"
        android:textStyle="bold"
        android:visibility="visible" />

</LinearLayout>

Create your custom adapter for ListView

You must override getViewTypeCount() method. This method returns the number of types of Views that will be created by getView method.

package com.javatechig;

import java.util.ArrayList;
import java.util.TreeSet;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.TextView;

class CustomAdapter extends BaseAdapter {

	private static final int TYPE_ITEM = 0;
	private static final int TYPE_SEPARATOR = 1;

	private ArrayList<String> mData = new ArrayList<String>();
	private TreeSet<Integer> sectionHeader = new TreeSet<Integer>();

	private LayoutInflater mInflater;

	public CustomAdapter(Context context) {
		mInflater = (LayoutInflater) context
				.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
	}

	public void addItem(final String item) {
		mData.add(item);
		notifyDataSetChanged();
	}

	public void addSectionHeaderItem(final String item) {
		mData.add(item);
		sectionHeader.add(mData.size() - 1);
		notifyDataSetChanged();
	}

	@Override
	public int getItemViewType(int position) {
		return sectionHeader.contains(position) ? TYPE_SEPARATOR : TYPE_ITEM;
	}

	@Override
	public int getViewTypeCount() {
		return 2;
	}

	@Override
	public int getCount() {
		return mData.size();
	}

	@Override
	public String getItem(int position) {
		return mData.get(position);
	}

	@Override
	public long getItemId(int position) {
		return position;
	}

	public View getView(int position, View convertView, ViewGroup parent) {
		ViewHolder holder = null;
		int rowType = getItemViewType(position);

		if (convertView == null) {
			holder = new ViewHolder();
			switch (rowType) {
			case TYPE_ITEM:
				convertView = mInflater.inflate(R.layout.snippet_item1, null);
				holder.textView = (TextView) convertView.findViewById(R.id.text);
				break;
			case TYPE_SEPARATOR:
				convertView = mInflater.inflate(R.layout.snippet_item2, null);
				holder.textView = (TextView) convertView.findViewById(R.id.textSeparator);
				break;
			}
			convertView.setTag(holder);
		} else {
			holder = (ViewHolder) convertView.getTag();
		}
		holder.textView.setText(mData.get(position));

		return convertView;
	}

	public static class ViewHolder {
		public TextView textView;
	}

}

Instantiate ListView in your activity

package com.javatechig;

import android.app.ListActivity;
import android.os.Bundle;

public class SectionListView extends ListActivity {

	private CustomAdapter mAdapter;

	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		mAdapter = new CustomAdapter(this);
		for (int i = 1; i < 30; i++) {
			mAdapter.addItem("Row Item #" + i);
			if (i % 4 == 0) {
				mAdapter.addSectionHeaderItem("Section #" + i);
			}
		}
		setListAdapter(mAdapter);
	}

}

Output

ListView with section header in android

Total
0
Shares
guest
11 Comments
Oldest
Newest Most Voted
Inline Feedbacks
View all comments
John Koch
John Koch
8 years ago

This worked great. Forgive me for asking cause I am new to this but now how would I add a click event to the rows (not the sections)

Yash Parikh
Yash Parikh
8 years ago

How to handle the click event of row?? Please post the code for handling row click….

Adrien Cerdan
Adrien Cerdan
8 years ago

If you want to add a Click listener on a row, put a listener on the listview :

setListAdapter(mAdapter);
ListView lv = (ListView) findViewById(android.R.id.list);
lv.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView parent, View v,
int position, long id) {
Toast.makeText(getBaseContext(), “Id = -1: ” + id, Toast.LENGTH_SHORT).show();
mAdapter.myCliquedPosition = position;
debug.print(“my pos in activity”+mAdapter.myCliquedPosition);
mAdapter.notifyDataSetInvalidated();
}
});

javatechig
javatechig
7 years ago

Thanks Felipe.

Riekelt Goucem
Riekelt Goucem
6 years ago

I’m kind of lost with the implementation in the code above. You mention “yourlistview”, but afaik we don’t use a listview? Also, more questions raised here as seen in the picture below:
http://prntscr.com/8bqjar

Nilanchala Panigrahy
Nilanchala Panigrahy
6 years ago
Reply to  Riekelt Goucem

ListActivities have an OnListItemClick built-in, the callback has a slightly different name onListItemClick().

The following snippet helps:

@Override
protected void onListItemClick (ListView l, View v, int position, long id) {
//Write your own logic
}

Murt
Murt
6 years ago

Great Work. But you forgot about one this, that is crucial: “how to remove item”.

NotifyDataSetChange moves item in place of section, and moves section in place of item.
Also you should add method that remove section when it has no items.
If you have time please add it here.

But overall very good job.

Best.

Asef Ratul
Asef Ratul
5 years ago

Hi, this article is very helpful for new comer like me. I have a question about the section header style. Its background is black and text is center aligned. I cant find any code for this in the customAdapter class. How do I change the background color and alignment?

Thanks in advance.

Nilanchala Panigrahy
Nilanchala Panigrahy
5 years ago
Reply to  Asef Ratul

The snippet_item2.xml layout is basically does the trick. You can change the background color to color of your choice using

android:background=”#2F2F2F”

or remove the gravity to remove the center alignment.

Ardiansyah Putra
Ardiansyah Putra
5 years ago

I used ListView with Activity but it wasn’t clickable

Gopal Awasthi
Gopal Awasthi
2 years ago

can we add the footers as well for different sections

Previous Post
Java Tutorials

Java TreeSet Example

Next Post
Android Tutorials

How to Drag a View in Android

Related Posts
By clicking “Allow All”, you agree to the storing of cookies on your device to enhance site navigation, analyze site usage, and assist in our marketing efforts. Cookie Notice
Allow All
11
0
Would love your thoughts, please comment.x
()
x