Expandable ListView in Android

Hello Friends,

Today,I will explain you about Expandable listview in android that what is actually Expandable Listview and how it works with simple example.

ExpandableListView is very useful when you want to sort lists into categories.
Like: If you want to make an app for downloading movies and  you might want to categories them by genre, so you can navigate through them easier using ExpandableListView.

A view that shows items in a vertically scrolling two-level list. This differs from the ListView by allowing two levels: groups which can individually be expanded to show its children. The items come from the  ExpandableListAdapter associated with this view.

Now, We will go through one simple example so you can get some idea.

1)  Lets first create a new Android project and name it “indies.expandListViewDemo”
and the build target for Android 2.2, and next set the following:
Application name: Movie expListView
Package name: com.indies.expandListView
Create Activity (Checked): MovieActivity
Then press Finish.

2)Basic Layout:

The layout is fairly simple.
Go to res->layout and open the file main.xml
There you’ll only find a LinearLayout and a TextView.
Remove the TextView and add the following

<ExpandableListView
android:id="@+id/ExpListview"
android:layout_height="match_parent"
android:layout_width="match_parent"
android:groupIndicator="@null" />

So now, the code should look like this

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android=<i>"http://schemas.android.com/apk/res/android"</i>
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical"
android:background="#000000"
android:paddingLeft="5dip"
android:paddingRight="5dip"
android:paddingTop="5dip">

<ExpandableListView
android:id="@+id/ExpListView"
android:layout_height="match_parent"
android:layout_width="match_parent"
android:cacheColorHint="#000000"
android:groupIndicator="@null"/>
</LinearLayout>

3)  Creating  classes for handle the data

Let’s start out by creating a new package in the src-folder and name com.indies.expandListView.Classes
In this package we are going to create 2 class-files, one named ExpandListGroup.java, and the other name ExpandListChild.java.
In this code we will only get and set the values.

The ExpandListChild.java is going to hold 1 value  Name :

package com.indies.expandListView.Classes;

public class ExpandListChild {

private String Name;
public String getName() {
return Name;
}

public void setName(String Name) {
this.Name = Name;
}}

And the ExpandListGroup.java is going to hold 2 values called Name and Items

package com.indies.expandListView.Classes;

import java.util.ArrayList;

public class ExpandListGroup {

private String Name;
private ArrayList<ExpandListChild> Items;

public String getName() {
return Name;
}

public void setName(String name) {
this.Name = name;
}

public ArrayList<ExpandListChild> getItems() {
return Items;
}
}

4) The Adapter: Here is the somewhat tricky part. the ExpandListAdapter, this is the code that will handle the Items so they can be displayed. For this part we are going to create a new package, and we are naming it com.indies.expandListView.Adapter In this package we are going to create a new class called ExpandListAdapter.java Here is the code for that class

package com.indies.expandListView.Adapter;

import java.util.ArrayList;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseExpandableListAdapter;
import android.widget.ExpandableListView;
import android.widget.ImageView;
import android.widget.TextView;

import android.widget.ExpandableListView.OnGroupCollapseListener;
import android.widget.ExpandableListView.OnGroupExpandListener;
import com.indies.expandListView.Classes.ExpandListGroup;
import com.indies.expandListView.Classes.ExpandListChild;
import com.indies.expandListView.R;

public class ExpandListAdapter extends BaseExpandableListAdapter {

private Context context;
private ArrayList<ExpandListGroup> groups;
private ExpandableListView mExpandableListView;
private int[] groupStatus;

public ExpandListAdapter(Context context,ExpandableListView pExpandableListView, ArrayList<ExpandListGroup> groups) {

this.context = context;
this.groups = groups;
mExpandableListView=pExpandableListView;
groupStatus = new int[groups.size()];
setListEvent();
}

private void setListEvent() {
mExpandableListView.setOnGroupExpandListener(new OnGroupExpandListener() {

@Override
public void onGroupExpand(int arg0) {
groupStatus[arg0] = 1;
}
});

mExpandableListView.setOnGroupCollapseListener(new OnGroupCollapseListener() {

@Override
public void onGroupCollapse(int arg0) {
groupStatus[arg0] = 0;
}
});
}

public void addItem(ExpandListChild item, ExpandListGroup group) {

if (!groups.contains(group)) {
groups.add(group);
}

int index = groups.indexOf(group);
ArrayList<ExpandListChild> ch = groups.get(index).getItems();
ch.add(item);
groups.get(index).setItems(ch);
}

public Object getChild(int groupPosition, int childPosition) {

ArrayList<ExpandListChild> chList = groups.get(groupPosition).getItems();
return chList.get(childPosition);
}

public long getChildId(int groupPosition, int childPosition) {
return childPosition;
}

public View getChildView(int groupPosition, int childPosition, boolean isLastChild, View view,

ViewGroup parent) {
ExpandListChild child = (ExpandListChild) getChild(groupPosition, childPosition);

if (view == null) {
LayoutInflater infalInflater = (LayoutInflater) context.getSystemService(context.LAYOUT_INFLATER_SERVICE);
view = infalInflater.inflate(R.layout.<i>expandlist_child_item</i>, null);
}

TextView tv = (TextView) view.findViewById(R.id.<i>item_title);
tv.setText(child.getName().toString());
return view;
}

public int getChildrenCount(int groupPosition) {

ArrayList<ExpandListChild> chList = groups.get(groupPosition).getItems();
return chList.size();
}

public Object getGroup(int groupPosition) {
return groups.get(groupPosition);
}

public int getGroupCount() {
return groups.size();
}

public long getGroupId(int groupPosition) {
return groupPosition;
}

public View getGroupView(int arg0, boolean arg1, View arg2, ViewGroup arg3)  {

GroupHolder groupHolder;

if (arg2 == null) {
arg2 = LayoutInflater.from(this.context).inflate(R.layout.expandlist_group_item,null);

groupHolder = new GroupHolder();
groupHolder.img = (ImageView) arg2.findViewById(R.id.tag_img);
groupHolder.title = (TextView) arg2.findViewById(R.id.group_title);
arg2.setTag(groupHolder);
}
else
{
groupHolder = (GroupHolder) arg2.getTag();
}

if (groupStatus[arg0] == 0) {

groupHolder.img.setImageResource(R.drawable.down_arrow);
}
else {

groupHolder.img.setImageResource(R.drawable.up_arrow);
}

groupHolder.title.setText(groups.get(arg0).getName());
return arg2;
}

class GroupHolder {
ImageView img;
TextView title;
}

public boolean hasStableIds() {
return true;
}

public boolean isChildSelectable(int arg0, int arg1) {
return true;
}

}

Above code gets each group and draws it on the screen in the correct order. Then, when you expand one of them, it gets the Childs and draws them on the screen in the correct order. Above code also sets the displayed text for each group and child.

5)  Group and child layout Lets go into the res->layout and add 2 new xml files named expandlist_child_item.xml and expandlist_group_item.xml The code for each of them are very  simple. For the expandlist_group_item.xml

<?xml version=<i>"1.0"</i> encoding=<i>"utf-8"</i>?>
<RelativeLayout xmlns:android=<i>"http://schemas.android.com/apk/res/android"</i>

android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:baselineAligned="false"
android:paddingTop="5dip">

<LinearLayout
android:layout_width="fill_parent"
android:layout_height="70dp"
android:background="#13a0d5"
android:gravity="center_vertical">

<TextView
android:id="@+id/group_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_centerVertical="true"
android:layout_marginLeft="15dip"
android:textColor="#ffffff"
android:textSize="25dip"
android:textStyle="bold"/>
</LinearLayout>

<ImageView
android:id="@+id/tag_img"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:layout_alignParentRight="true"
android:src="@drawable/down_arrow"/>

</RelativeLayout>

Now, For the expandlist_child_item.xml

<?xml version=<i>"1.0" encoding="utf-8"?>
<LinearLayout xmlns:android=<i>"http://schemas.android.com/apk/res/android"</i>

android:id="@+id/groupItem"
android:layout_width="0dip"
android:layout_height="fill_parent"
android:layout_weight="1"
android:background="#0b5c7a"
android:clickable="true" >

<TextView
android:id="@+id/item_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="15dip"
android:layout_marginLeft="15dip"
android:text="sample"
android:textColor="#ffffff"
android:textSize="20sp"/>
</LinearLayout>

6)  Activity: Go in to src->com.indies.expandListView and open the MainActivity.java This is the code you’ll see.


package com.indies.expandListView;

import java.util.ArrayList;
import com.indies.expandListView.Adapter.ExpandListAdapter;
import com.indies.expandListView.Classes.*;

import android.app.Activity;
import android.os.Bundle;
import android.widget.ExpandableListView;

public class MovieActivity extends Activity {
    /** Called when the activity is first created. */
	private ExpandListAdapter ExpAdapter;
	private ArrayList<ExpandListGroup> ExpListItems;
	private ExpandableListView ExpandList;
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        ExpandList = (ExpandableListView) findViewById(R.id.ExpListView);
        ExpListItems = SetStandardGroups();
        ExpAdapter=new ExpandListAdapter(getApplicationContext(),ExpandList,ExpListItems);
        ExpandList.setAdapter(ExpAdapter);
    }

    public ArrayList<ExpandListGroup> SetStandardGroups() {
    	ArrayList<ExpandListGroup> list = new ArrayList<ExpandListGroup>();
    	ArrayList<ExpandListChild> list2 = new ArrayList<ExpandListChild>();
        ExpandListGroup gru1 = new ExpandListGroup();
        gru1.setName("Action Movies");
        ExpandListChild ch1_1 = new ExpandListChild();
        ch1_1.setName("The Dark night");

        list2.add(ch1_1);
        ExpandListChild ch1_2 = new ExpandListChild();
        ch1_2.setName("Ghayal");
        list2.add(ch1_2);
        ExpandListChild ch1_3 = new ExpandListChild();
        ch1_3.setName("Sigham");
        list2.add(ch1_3);
        gru1.setItems(list2);
        list2 = new ArrayList<ExpandListChild>();

        ExpandListGroup gru2 = new ExpandListGroup();
        gru2.setName("Commmedy");
        ExpandListChild ch2_1 = new ExpandListChild();
        ch2_1.setName("Heraferi");
        list2.add(ch2_1);
        ExpandListChild ch2_2 = new ExpandListChild();
        ch2_2.setName("Chupke Chupke");
        list2.add(ch2_2);
        ExpandListChild ch2_3 = new ExpandListChild();
        ch2_3.setName("HouseFull-2");
        list2.add(ch2_3);
        gru2.setItems(list2);
        list.add(gru1);
        list.add(gru2);

        return list;
    }
}
 

Now we set some default items to a list, load the list to the Adapter, and apply the adapter to the ExpandableListView The finished product of this tutorial will look like this

image

Hope it helps.HaPpY Coding. 🙂

Speak Your Mind

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: