Android ExpandableListView Example

android.widget.ExpandableListView is a subclass of ListView. It divides the list items into several groups, each group contains multiple list items. To display data in it, you need to create an ExpandableListAdapter, and then override it’s several methods to provide group view item an child view item.

1. Steps To Use ExpandableListView.

  1. Create a layout xml file, add ExpandableListView xml element in it.
  2. Create an ExpandableListAdapter instance in activity java file.
  3. Get the ExpandableListView object in activity java file.
  4. Invoke ExpandableListView  setAdapter() method to set the data adapter for it.

2. ExpandableListAdapter Methods.

  1. getGroupCount() : Return the group item count.
  2. getChildrenCount(int groupIndex) : Return child item count in specified group by group index.
  3. getGroup(int groupIndex) : Return group object, commonly a String.
  4. getChild(int groupIndex, int childIndex) : Return specified child object by child index in specified group by group index.
  5. getGroupView(int groupIndex, boolean isExpanded, View view, ViewGroup viewGroup) : Return a View object that will be displayed for specified group item by groupIndex.
  6. getChildView(int groupIndex, int childIndex, boolean isLastChild, View view, ViewGroup viewGroup) : Return a View object that will be displayed for specified group child item.

3. ExpandableListView Example.

If you can not watch the above video, you can see it on the youtube URL https://youtu.be/hU_Q-u1GGZo

activity_expandable_list_view.xml

<ExpandableListView
    android:id="@+id/expandableListView"
    android:layout_width="match_parent"
    android:layout_height="match_parent" />

ExpandableListViewActivity.java

package com.dev2qa.example;

import android.database.DataSetObserver;
import android.graphics.Color;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ExpandableListAdapter;
import android.widget.ExpandableListView;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class ExpandableListViewActivity extends AppCompatActivity {

    // Store group data.
    private List<String> groupList = null;
    // Store child data. Key is the group value, Value is the child data in a list.
    private Map<String, List<String>> childListMap = null;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_expandable_list_view);

        setTitle("dev2qa.com --- Expandable List View Example.");

        this.addUserInfo("Jerry", 35, "Engineer", "[email protected]");
        this.addUserInfo("Richard", 25, "Engineer", "[email protected]");
        this.addUserInfo("Tom", 35, "Engineer", "[email protected]");
        this.addUserInfo("Jack", 25, "Tester", "[email protected]");
        this.addUserInfo("Kevin", 35, "Tester", "[email protected]");

        // Create an ExpandableListAdapter object, this object will be used to provide data to ExpandableListView.
        ExpandableListAdapter expandableListAdapter = new ExpandableListAdapter() {
            @Override
            public void registerDataSetObserver(DataSetObserver dataSetObserver) {

            }

            @Override
            public void unregisterDataSetObserver(DataSetObserver dataSetObserver) {

            }

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

            @Override
            public int getChildrenCount(int groupIndex) {
                String group = groupList.get(groupIndex);
                List<String> childInfoList = childListMap.get(group);
                return childInfoList.size();
            }

            @Override
            public Object getGroup(int groupIndex) {
                return groupList.get(groupIndex);
            }

            @Override
            public Object getChild(int groupIndex, int childIndex) {
                String group = groupList.get(groupIndex);
                List<String> childInfoList = childListMap.get(group);
                return childInfoList.get(childIndex);
            }

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

            @Override
            public long getChildId(int groupIndex, int childIndex) {
                return childIndex;
            }

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

            // This method will return a View object displayed in group list item.
            @Override
            public View getGroupView(int groupIndex, boolean isExpanded, View view, ViewGroup viewGroup) {
                // Create the group view object.
                LinearLayout groupLayoutView = new LinearLayout(ExpandableListViewActivity.this);
                groupLayoutView.setOrientation(LinearLayout.HORIZONTAL);

                // Create and add an imageview in returned group view.
                ImageView groupImageView = new ImageView(ExpandableListViewActivity.this);
                if(isExpanded) {
                    groupImageView.setImageResource(R.mipmap.ic_launcher_round);
                }else
                {
                    groupImageView.setImageResource(R.mipmap.ic_launcher);
                }
                groupLayoutView.addView(groupImageView);

                // Create and add a textview in returned group view.
                String groupText = groupList.get(groupIndex);
                TextView groupTextView = new TextView(ExpandableListViewActivity.this);
                groupTextView.setText(groupText);
                groupTextView.setTextSize(30);
                groupLayoutView.addView(groupTextView);

                return groupLayoutView;
            }

            // This method will return a View object displayed in child list item.
            @Override
            public View getChildView(int groupIndex, int childIndex, boolean isLastChild, View view, ViewGroup viewGroup) {
                // First get child text/
                Object childObj = this.getChild(groupIndex, childIndex);
                String childText = (String)childObj;

                // Create a TextView to display child text.
                TextView childTextView = new TextView(ExpandableListViewActivity.this);
                childTextView.setText(childText);
                childTextView.setTextSize(20);
                childTextView.setBackgroundColor(Color.GREEN);

                // Get group image width.
                Drawable groupImage = getDrawable(R.mipmap.ic_launcher);
                int groupImageWidth = groupImage.getIntrinsicWidth();

                // Set child textview offset left. Then it will align to the right of the group image.
                childTextView.setPadding(groupImageWidth,0,0,0);

                return childTextView;
            }

            @Override
            public boolean isChildSelectable(int groupIndex, int childIndex) {
                return false;
            }

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

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

            @Override
            public void onGroupExpanded(int groupIndex) {

            }

            @Override
            public void onGroupCollapsed(int groupIndex) {


            }

            @Override
            public long getCombinedChildId(long groupIndex, long childIndex) {
                return 0;
            }

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

        final ExpandableListView expandableListView = (ExpandableListView)findViewById(R.id.expandableListView);
        expandableListView.setAdapter(expandableListAdapter);

        // Add on group expand listener.
        expandableListView.setOnGroupExpandListener(new ExpandableListView.OnGroupExpandListener() {
            @Override
            public void onGroupExpand(int groupIndex) {
                // Get total group size.
                int groupListSize = groupList.size();

                // Close other expanded group.
                for(int i=0;i < groupListSize; i++) {
                    if(i!=groupIndex) {
                        expandableListView.collapseGroup(i);
                    }
                }
            }
        });
    }

    // Add user info in group and child object.
    private void addUserInfo(String name, int age, String title, String email)
    {
        if(this.groupList == null)
        {
            this.groupList = new ArrayList<String>();
        }

        if(this.childListMap == null)
        {
            this.childListMap = new HashMap<String, List<String>>();
        }

        if(!this.groupList.contains(name)) {
            this.groupList.add(name);
        }

        // Create child list.
        List<String> childList = new ArrayList<String>();
        childList.add("Title : " + title);
        childList.add("Age : " + String.valueOf(age));
        childList.add("Email : " + email);
        // Add child data list in the map, key is group name.
        this.childListMap.put(name, childList);
    }
}

Leave a Comment

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

This site uses Akismet to reduce spam. Learn how your comment data is processed.