ExpandableListAdapter Tutorial With Example In Android Studio

ExpandableListAdapter is an Adapter that links the ExpandableListView with the underlying data. The implementation of this interface will provide the data for the children and also initiate the views for the children and groups.  For customization of List we need to implement ExpandableListAdapter in our custom Adapter.

ExpandableListAdapter in Android

It is important to remember that Adapter acts a bridge between UI component and data source that helps us to fill data in UI component. Here in simple words we can say an Adapter is that which links an ExpandableListView with the underlying data. The implementation of this Interface will provide access to the data of the children (categorized by groups), and also instantiate views for the children and groups.

ExpandableListAdapter Example

Below is the example code of ExpandableListAdapter in which we create an custom Adapter class named “ MyExpandableListAdapter ” and then implements expandable list adapter in that class.

public class MyExpandableListAdapter implements ExpandableListAdapter {
@Override
public void registerDataSetObserver(DataSetObserver observer) {

}

@Override
public void unregisterDataSetObserver(DataSetObserver observer) {

}

@Override
public int getGroupCount() {
return 0;
}

@Override
public int getChildrenCount(int groupPosition) {
return 0;
}

@Override
public Object getGroup(int groupPosition) {
return null;
}

@Override
public Object getChild(int groupPosition, int childPosition) {
return null;
}

@Override
public long getGroupId(int groupPosition) {
return 0;
}

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

@Override
public boolean hasStableIds() {
return false;
}

@Override
public View getGroupView(int groupPosition, boolean isExpanded, View convertView, ViewGroup parent) {
return null;
}

@Override
public View getChildView(int groupPosition, int childPosition, boolean isLastChild, View convertView, ViewGroup parent) {
return null;
}

@Override
public boolean isChildSelectable(int groupPosition, int childPosition) {
return false;
}

@Override
public boolean areAllItemsEnabled() {
return false;
}

@Override
public boolean isEmpty() {
return false;
}

@Override
public void onGroupExpanded(int groupPosition) {

}

@Override
public void onGroupCollapsed(int groupPosition) {

}

@Override
public long getCombinedChildId(long groupId, long childId) {
return 0;
}

@Override
public long getCombinedGroupId(long groupId) {
return 0;
}
}

In the above code snippet we see the overrided methods of ExpandableListAdapter which are used to set the data in the ExpandableListView. Below is the description of  all these methods:

1. registerDataSetObserver(DataSetObserver observer): This method is used to register an observer that is called when changes happen to the data used by this adapter.

Parameters:

  • observer: The object that gets notified when the data set changes.

2. unregisterDataSetObserver(DataSetObserver observer): This method is used to unregister an observer that is called when changes happen to the data used by this adapter.

Parameters:

  • observer: The object that gets notified when the data set changes.

3. getGroupCount(): This function is used to get the total number of groups.

4. getChildrenCount(int groupPosition): This function gets the number of children in a specified group.

Parameters:

  • groupPosition: This is the parameter that tells the position for the parent or group of the child and by using that position we calculate the number of children in that group.

5. getGroup(int groupPosition): This method gets the data associated with the given group.

Parameters:

  • groupPosition: This parameter tells the position for the parent or group of the child. This function returns an integer type value

6. getChild(int groupPosition, int childPosition): This method gets the data associated with the given child within the given group.

Parameters:

  • groupPosition: This is the first parameter that tells the position for the parent or group of the child. This function returns an integer type value
  • childPosition: This is the second parameter that tells the position for the child of the given group. This function returns an integer type value.

7. getGroupId(int groupPosition): This function is used to get the ID for the group at the given position.

Parameters:

  • groupPosition: This parameter tells the position for the parent or group of the child and by using that position we get the ID for the group.

8. getChildId(int groupPosition, int childPosition): This function is used to gets the ID for the given child within the given group.

Parameters:

  • groupPosition: This is the first parameter that tells the position for the parent or group of the child. This function returns an integer type value
  • childPosition: This is the second parameter that tells the position for the child of the given group. This function returns an integer type value and by using that value we gets the ID for that.

9. hasStableIds(): This method Indicates that whether the child and group ID’s are stable across changes to the underlying data.

10. getGroupView(int groupPosition, boolean isExpanded, View convertView, ViewGroup parent): This method is used when we need to create our group or parent View .

Paramters:

  • groupPosition: This is the first parameter that tells the position for the parent or group of the child. The function returns an integer type value.
  • isExpanded: This is the second parameter that returns Boolean value. It returns true if the current group is expanded and false if it’s not.
  • convertView: This is the fourth parameter that returns View which is used to set the layout for group items.
  • Parent: This is the fifth or last parameter that is used to set the view for the parent or group item.  The eventual parent of this new View

11. getChildView(int groupPosition, int childPosition, boolean isLastChild, View convertView, ViewGroup parent): This method is  used when we need to create a child View means a child item for a parent or group.

Paramters:

  • groupPosition: This is the first parameter that tells the position for the parent(group) of the current child. The function returns an integer type value.
  • childPosition: This is the second parameter that tells the position for current child item of the parent.
  • isLastChild: This is the third parameter that returns Boolean value. It returns true if the current child item is the last child within its group and false if it’s not.
  • convertView: This is the fourth parameter that returns View which is used to set the layout for child items.
  • Parent: parent is the fifth or last parameter that used to set the view for the parent or group item.  The eventual parent of this new View.

12. isChildSelectable(int groupPosition, int childPosition): This mehod checks whether the child at the specified position is selectable or not. This method returns an Boolean value means true or false. It returns true if the child is selectable and false if it’s not.

Parameters:

  • groupPosition: This is the first parameter that tells the position for the parent or group of the child. This function returns an integer type value.
  • childPosition: This is the second parameter that tells the position for the child of the given group. This function returns an integer type value and by using that value we checks whether the child is selectable or not.

13. areAllItemsEnabled(): This method tells that all the items of expandable list are enabled or not. This method returns Boolean type value means true or false . It returns true if all the items are enabled.

14. isEmpty(): This method returns an Boolean value that tells whether the item is empty or not.

15. onGroupExpanded(int groupPosition): This method is called when a group is collapsed.

Paramters:

  • groupPosition: This parameter tells the position for the parent or group of the child that has been expanded

16. onGroupCollapsed(int groupPosition): This method is called when a group is expanded.

Paramters:

  • groupPosition: This parameter tells the position for the parent or group of the child that has been collapsed.

17. getCombinedChildId(long groupId, long childId): This method is used to get an id for a group that unique any item ( either child or group ) that is in the list.

Parameters:

  • groupId: This parameter tells the ID of the group or parent that contains the child.
  • childId: This parameter tells the ID of the child.

18. getCombinedGroupId(long groupId): This method is used to get an id for a child that unique any item ( either child or group ) that is in the list.

Parameters:

  • groupId: This parameter tells the ID of the group or parent.

ExpandableListAdapter Example In Android Studio

Below is the example of ExpandableListAdapter in Android where we display an expandable list with song names according to category. In this example we display songs list name as group items and their songs names as child items for a particular group. In this we implement setOnChildClickListener and setOnGroupClickListener events and whenever a user clicks on a child or a group item the name of the item ( song or songs list name) is display by using a Toast.

Below is the final output, download code and step by step explanation:

Download Code (Password: abhiandroid) ?

ExpandableListAdapter Example In Android Studio

Step 1: Create a new project and name it ExpandableListAdapter.

Step 2: Open res -> layout ->activity_main.xml (or) main.xml and add following code :

In this step we open an xml file and add the code for displaying ExpandableListView by using its different attributes.

<?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">

    <ExpandableListView
        android:id="@+id/simpleExpandableListView"
        android:layout_width="match_parent"
        android:layout_height="fill_parent"
        android:divider="#0f0"
        android:dividerHeight="1dp" />

</RelativeLayout>

Step 3: Create a new xml file for group items Open res -> layout -> group_items.xml and add following code:

In this step we add the code for displaying a Textview for Song Category names.

<?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="55dip"
    android:orientation="vertical" >

    <TextView
        android:id="@+id/heading"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:paddingLeft="35sp"
        android:textAppearance="?android:attr/textAppearanceLarge"
        android:textStyle="bold" />

</LinearLayout>

Step 4: Create a new xml file for group items Open res -> layout -> child_items.and add following code:

In this step we add the code for displaying TextView for song name.

<?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">

    <TextView
        android:id="@+id/childItem"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentTop="true"
        android:layout_marginLeft="10dp"
        android:textAppearance="?android:attr/textAppearanceMedium" />

</RelativeLayout>

Step 5: Open src -> package -> MainActivity.java

In this step we open MainActivity where we add the code to initiate the ExpandableListView and then add the data to list for displaying in a ExpandableListView using model classes. Finally set the Adapter that fills the data in the ExpandableListView. In this we also implement setOnChildClickListener and setOnGroupClickListener events so whenever a user clicks on a child or a group item the name of the item ( song or song list name ) is display by using a Toast.

package example.abhiandroid.ExpandableListAdapterExample;

import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.ExpandableListView;
import android.widget.Toast;

import java.util.ArrayList;
import java.util.LinkedHashMap;

public class MainActivity extends AppCompatActivity {

    private LinkedHashMap<String, GroupItemsInfo> songsList = new LinkedHashMap<String, GroupItemsInfo>();
    private ArrayList<GroupItemsInfo> deptList = new ArrayList<GroupItemsInfo>();

    private MyExpandableListAdapter myExpandableListAdapter;
    private ExpandableListView simpleExpandableListView;


    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        // add data for displaying in expandable list view
        loadData();

        //get reference of the ExpandableListView
        simpleExpandableListView = (ExpandableListView) findViewById(R.id.simpleExpandableListView);
        // create the adapter by passing your ArrayList data
        myExpandableListAdapter = new MyExpandableListAdapter(MainActivity.this, deptList);
        // attach the adapter to the expandable list view
        simpleExpandableListView.setAdapter(myExpandableListAdapter);

        // setOnChildClickListener listener for child row click or song name click
        simpleExpandableListView.setOnChildClickListener(new ExpandableListView.OnChildClickListener() {
            @Override
            public boolean onChildClick(ExpandableListView parent, View v, int groupPosition, int childPosition, long id) {
                //get the group header
                GroupItemsInfo headerInfo = deptList.get(groupPosition);
                //get the child info
                ChildItemsInfo detailInfo = headerInfo.getSongName().get(childPosition);
                //display it or do something with it
                Toast.makeText(getBaseContext(), " List And Song Is :: " + headerInfo.getName()
                        + "/" + detailInfo.getName(), Toast.LENGTH_LONG).show();
                return false;
            }
        });
        // setOnGroupClickListener listener for group Song List click
        simpleExpandableListView.setOnGroupClickListener(new ExpandableListView.OnGroupClickListener() {
            @Override
            public boolean onGroupClick(ExpandableListView parent, View v, int groupPosition, long id) {
                //get the group header
                GroupItemsInfo headerInfo = deptList.get(groupPosition);
                //display it or do something with it
                Toast.makeText(getBaseContext(), " List Name :: " + headerInfo.getName(),
                        Toast.LENGTH_LONG).show();

                return false;
            }
        });


    }

    // load some initial data into out list
    private void loadData() {

        addProduct("Latest Punjabi Songs", "Tere Bagair - Amrinder Gill");
        addProduct("Latest Punjabi Songs", "Khaab - Akhil");
        addProduct("Latest Punjabi Songs", "Dil - Ninja");

        addProduct("Top 50 Songs", "Tere Bagair- Amrinder Gill");
        addProduct("Top 50 Songs", "Attt Karti - Jassi Gill");

        addProduct("Top Of This Week", "Khaab- Akhil");
        addProduct("Top Of This Week", "Tere Bagair- Amrinder Gill");
        addProduct("Top Of This Week", "Gal Sun Ja - Kanwar Chahal");

    }


    // here we maintain songsList and songs names
    private int addProduct(String songsListName, String songName) {

        int groupPosition = 0;

        //check the hashmap if the group already exists
        GroupItemsInfo headerInfo = songsList.get(songsListName);
        //add the group if doesn't exists
        if (headerInfo == null) {
            headerInfo = new GroupItemsInfo();
            headerInfo.setName(songsListName);
            songsList.put(songsListName, headerInfo);
            deptList.add(headerInfo);
        }

        // get the children for the group
        ArrayList<ChildItemsInfo> productList = headerInfo.getSongName();
        // size of the children list
        int listSize = productList.size();
        // add to the counter
        listSize++;

        // create a new child and add that to the group
        ChildItemsInfo detailInfo = new ChildItemsInfo();
        detailInfo.setName(songName);
        productList.add(detailInfo);
        headerInfo.setPlayerName(productList);

        // find the group position inside the list
        groupPosition = deptList.indexOf(headerInfo);
        return groupPosition;
    }

}

Step 6: Create a New Class Open -> package – > GroupItemsInfo.Java and add the following code.

In this step we create an class for set and get the group item name and child items info according to a particular group. GroupItemsInfo is a model class used to set the name of the group item and child items information from your MainActivity and then get the information within Adapter class. Finally set the value to ExpandableListView.

package example.abhiandroid.ExpandableListAdapterExample;

import java.util.ArrayList;

public class GroupItemsInfo {

    private String listName;
    private ArrayList<ChildItemsInfo> list = new ArrayList<ChildItemsInfo>();

    public String getName() {
        return listName;
    }

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

    public ArrayList<ChildItemsInfo> getSongName() {
        return list;
    }

    public void setPlayerName(ArrayList<ChildItemsInfo> songName) {
        this.list = songName;
    }

}

Step 7: Create a New Class Open -> package – > ChildItemsInfo.Java and add the following code.

In this step we create a class to set and get the name for the child item. ChildItemsInfo is also model class used to set the name of the child item from your MainActivity and then get the name within Adapter class. Finally set the value to ExpandableListView.

package example.abhiandroid.ExpandableListAdapterExample;

public class ChildItemsInfo {

    private String songName = "";

    public String getName() {
        return songName;
    }

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

}

Step 8: Create a New Class Open -> package – > MyExpandableListAdapter.Java and add the following code.

In this step we create a custom adapter named “MyExpandableListAdapter” and then implements ExpandableListAdapter in that class. Finally we set the data in the ExpandableListView from GroupItemsInfo and ChildItemsInfo model classes.

package example.abhiandroid.ExpandableListAdapterExample;

import android.content.Context;
import android.database.DataSetObserver;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ExpandableListAdapter;
import android.widget.TextView;

import java.util.ArrayList;

/**
 * Created by Gourav for AbhiAndroid on 19-03-2016.
 */
public class MyExpandableListAdapter implements ExpandableListAdapter {

    private Context context;
    private ArrayList<GroupItemsInfo> teamName;

    public MyExpandableListAdapter(Context context, ArrayList<GroupItemsInfo> deptList) {
        this.context = context;
        this.teamName = deptList;
    }
    @Override
    public void registerDataSetObserver(DataSetObserver observer) {

    }

    @Override
    public void unregisterDataSetObserver(DataSetObserver observer) {

    }

    @Override
    public int getGroupCount() {
        return teamName.size();
    }

    @Override
    public int getChildrenCount(int groupPosition) {
        ArrayList<ChildItemsInfo> productList = teamName.get(groupPosition).getSongName();
        return productList.size();
    }

    @Override
    public Object getGroup(int groupPosition) {
        return teamName.get(groupPosition);
    }

    @Override
    public Object getChild(int groupPosition, int childPosition) {
        ArrayList<ChildItemsInfo> productList = teamName.get(groupPosition).getSongName();
        return productList.get(childPosition);
    }

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

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

    @Override
    public boolean hasStableIds() {
        return true;
    }

    @Override
    public View getGroupView(int groupPosition, boolean isExpanded, View convertView, ViewGroup parent) {
        GroupItemsInfo headerInfo = (GroupItemsInfo) getGroup(groupPosition);
        if (convertView == null) {
            LayoutInflater inf = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
            convertView = inf.inflate(R.layout.group_items, null);
        }

        TextView heading = (TextView) convertView.findViewById(R.id.heading);
        heading.setText(headerInfo.getName().trim());
        return convertView;

    }

    @Override
    public View getChildView(int groupPosition, int childPosition, boolean isLastChild, View convertView, ViewGroup parent) {
        ChildItemsInfo detailInfo = (ChildItemsInfo) getChild(groupPosition, childPosition);
        if (convertView == null) {
            LayoutInflater infalInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
            convertView = infalInflater.inflate(R.layout.child_items, null);
        }
        TextView childItem = (TextView) convertView.findViewById(R.id.childItem);
        childItem.setText(detailInfo.getName().trim());

        return convertView;
    }

    @Override
    public boolean isChildSelectable(int groupPosition, int childPosition) {
        return true;
    }

    @Override
    public boolean areAllItemsEnabled() {
        return false;
    }

    @Override
    public boolean isEmpty() {
        return false;
    }

    @Override
    public void onGroupExpanded(int groupPosition) {

    }

    @Override
    public void onGroupCollapsed(int groupPosition) {

    }

    @Override
    public long getCombinedChildId(long groupId, long childId) {
        return 0;
    }

    @Override
    public long getCombinedGroupId(long groupId) {
        return 0;
    }
}

Output:

Now run the App in AVD and you will see ExpandableListView listing song names according to category. This all we created using ExpandableListAdapter.

  • Is this article helps you understand?
  • YES   NO

2 thoughts on “ExpandableListAdapter Tutorial With Example In Android Studio”

  1. Thanks..! I had tried a lot but my code didn’t work then i find this code and i able to solve my problem thanks a lot…

Leave a Reply

Your email address will not be published. Required fields are marked *