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

Madhumita

She is self-motivated enthusiastic techie spending most of her time in writing code. She loves coding, android and java. She has developed her software personality with understanding on various tools and technologies and hands on experience on app development.

Related Articles

Join The Discussion

Please note: We reserve the right to delete comments that contains snarky remarks, offensive or off-topic. To know more read our comments policy.
  • Ardiansyah Putra

    I used ListView with Activity but it wasn’t clickable

  • Asef Ratul

    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.

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

  • Murt

    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.

  • Riekelt Goucem

    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

    • 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
      }

  • Thanks Felipe.

  • Adrien Cerdan

    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();
    }
    });

  • Yash Parikh

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

  • John Koch

    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)