Greetings!
We have recently published 100+ articles on android tutorials with kotlin and java. If you need, you may visit Android Tutorial for beginners page. You can also check Kotlin Tutorial for beginners. Also, if you are interested in content writing, you can mail us at tutorialwing@gmail.com.Note – We have used another widget textView in this tutorial. So, you may visit our tutorial on android textView in Kotlin.
if you wish to know more, you may visit official link of – this widget.
TABLE OF CONTENT
- Demo Output
- SourceCode(Kotlin)
- Getting Started
- Example of ExpandableListView
- 1. Create New Project
- 2. Update Values Folder
- 3. Create View For Child
- 4. Create View For Group
- 5. Create Adapter For ExpandableListView
- 6. Use ExpandableListView in xml
- 7. Access ExpandableListView in kotlin
- 8.1 Setting GroupExpandListener in ExpandableListView
- 8.2 Setting GroupCollapsedListener in ExpandableListView
- 8.3 Setting ChildClickListener in ExpandableListView
Output

ExpandableListView Tutorial output
SourceCode (Kotlin)
[emaillocker id=”4963″]
ExpandableListView
[/emaillocker]
Getting Started
Android ExpandableListView can be defined as below –
ExpandableListView is a View that shows vertically scrolling two-level list. In this view, first level groups can be expanded to show it’s children items. ExpandableListView also shows an icon beside each group to show it’s status i.e. whether it is expanded or collapsed.
Note – You can not use value wrap_content for android:layout_height attribute of ExpandableListView if parent’s size is also not strictly specified. For example, if you have used ExpandableListView inside ScrollView, you can not use wrap_content for android:layout_height because ScrollView can have any height.
Example of Android ExpandableListView Using Kotlin
Now, we will see an example that shows how to use this widget in any android application. At first, we will create an application. Then, we will use expandableListView in it.
1. Creating New Project in Kotlin
Follow steps below to create new project. Please ignore the steps if you have already created the project.
Step | Description |
---|---|
1. | Open Android Studio. |
2. | Go to File => New => New Project. Write application name as ExpandableListView. Then, check Include Kotlin Support and click next button. |
3. | Select minimum SDK you need. However, we have selected 21 as minimum SDK. Then, click next button |
4. | Then, select Empty Activity => click next => click finish. |
5. | You will get a newly created project successfully if you have followed steps properly. |
2. Modify values folder
Open res/values/strings.xml file. Then, add below code into it.
<resources> <string name="app_name">ExpandableListView</string> </resources>
3. Create View For Child Item in ExpandableListView
Since we need an xml file that contains ui for a child item in expandableListView. So, create an xml file in main/res/layout folder with name list_item.xml.
Now, open main/res/layout/list_item.xml file and add below code into this file.
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="vertical"> <TextView android:id="@+id/expandedListItem" android:layout_width="match_parent" android:layout_height="wrap_content" android:paddingBottom="10dp" android:paddingLeft="?android:attr/expandableListPreferredChildPaddingLeft" android:paddingTop="10dp"/> </LinearLayout>
We are showing only name of an item in expandableListView. So, there is only textView in list_item.xml file.
4. Create View For Group Item in ExpandableListView
Now, we need an ui for group item in expandableListView. So, create an xml file, named list_group.xml, in main/res/layout folder.
Then, open main/res/layout/list_group.xml file and add below code into it.
<?xml version="1.0" encoding="utf-8"?> <LinearLayout 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/listTitle" android:layout_width="match_parent" android:layout_height="wrap_content" android:paddingBottom="10dp" android:paddingLeft="?android:attr/expandableListPreferredItemPaddingLeft" android:paddingTop="10dp" android:textColor="@android:color/black"/> </LinearLayout>
In each group item, we are showing only name of the group. So, we need only textView in xml file.
Till now, we have defined ui for a group and child item. Now, we will use this xml file in adapter class that provides data to the expandableListView.
5. Create Adapter For ExpandableListView
Now, we will create adapter for expandableListView that will be used to provide data to the view. So, create a kotlin file , named CustomExpandableListAdapter.kt, in main/java/com.tutorialwing.expandablelistview package.
Now, open main/java/com.tutorialwing.expandablelistview/CustomExpandableListAdapter.kt file and add below code into it.
package com.tutorialwing.expandablelistview import android.content.Context import android.graphics.Typeface import android.view.LayoutInflater import android.view.View import android.view.ViewGroup import android.widget.BaseExpandableListAdapter import android.widget.TextView import java.util.HashMap class CustomExpandableListAdapter internal constructor(private val context: Context, private val titleList: List<String>, private val dataList: HashMap<String, List<String>>) : BaseExpandableListAdapter() { override fun getChild(listPosition: Int, expandedListPosition: Int): Any { return this.dataList[this.titleList[listPosition]]!![expandedListPosition] } override fun getChildId(listPosition: Int, expandedListPosition: Int): Long { return expandedListPosition.toLong() } override fun getChildView(listPosition: Int, expandedListPosition: Int, isLastChild: Boolean, convertView: View?, parent: ViewGroup): View { var convertView = convertView val expandedListText = getChild(listPosition, expandedListPosition) as String if (convertView == null) { val layoutInflater = this.context.getSystemService(Context.LAYOUT_INFLATER_SERVICE) as LayoutInflater convertView = layoutInflater.inflate(R.layout.list_item, null) } val expandedListTextView = convertView!!.findViewById<TextView>(R.id.expandedListItem) expandedListTextView.text = expandedListText return convertView } override fun getChildrenCount(listPosition: Int): Int { return this.dataList[this.titleList[listPosition]]!!.size } override fun getGroup(listPosition: Int): Any { return this.titleList[listPosition] } override fun getGroupCount(): Int { return this.titleList.size } override fun getGroupId(listPosition: Int): Long { return listPosition.toLong() } override fun getGroupView(listPosition: Int, isExpanded: Boolean, convertView: View?, parent: ViewGroup): View { var convertView = convertView val listTitle = getGroup(listPosition) as String if (convertView == null) { val layoutInflater = this.context.getSystemService(Context.LAYOUT_INFLATER_SERVICE) as LayoutInflater convertView = layoutInflater.inflate(R.layout.list_group, null) } val listTitleTextView = convertView!!.findViewById<TextView>(R.id.listTitle) listTitleTextView.setTypeface(null, Typeface.BOLD) listTitleTextView.text = listTitle return convertView } override fun hasStableIds(): Boolean { return false } override fun isChildSelectable(listPosition: Int, expandedListPosition: Int): Boolean { return true } }
As we already know, this class provides data for an item to the expandableListView. We have inherited this class from BaseExpandableListAdapter class. A constructor has also been defined that accepts context, titleList and dataList. Then, we have overridden some of the methods in this class.
They are –
S. No. | Method | Description |
---|---|---|
1. | getChild() | It returns the data associated with child at given child position (i.e. expandedListPosition) in a given group (i.e. listPosition) . Actual method is getChild(listPosition: Int , expandedListPosition: Int): Any . |
2. | getChildId() | Returns id of the child at given child position (i.e. expandedListPosition) within group at given position (i.e. listPosition) . Actual method is getChildId(listPosition: Int, expandedListPosition: Int): Long . |
3. | getChildView() | Returns the view for the child at given position within a group at given position. Actual method is getChildView(listPosition: Int, expandedListPosition: Int, isLastChild: Boolean, convertView: View?, parent: ViewGroup): View . In this method, define the ui for the child element. You can check how we have defined the ui for any child element in getChildView() method in CustomExpandableListAdapter class. |
4. | getChildrenCount() | It returns the number of children in group at given position. Actual method is getChildrenCount(listPosition: Int): Int . |
5. | getGroup() | Returns the data associated with group at given position (i.e. listPosition). Actual method is getGroup(listPosition: Int): Any . |
6. | getGroupCount() | Returns the number of groups. Actual method is getGroupCount(): Int . |
7. | getGroupId() | Returns the id of the group at given position (i.e. listPosition). Actual method is getGroupId(listPosition: Int): Long. |
8. | getGroupView() | Return the view of group at given position (i.e. listPosition). Actual method is getGroupView(listPosition: Int, isExpanded: Boolean, convertView: View?, parent: ViewGroup): View. In this method, we define the view for group. Notice that how we have used list_group.xml file for any group in CustomExpandableListAdapter class. |
9. | hasStableIds() | It indicates whether group or child ids are stable across changes to the underlying data. |
10. | isChildSelectable() | It indicates whether child at given position in given group is selectable or not. Actual method is isChildSelectable(listPosition: Int, expandedListPosition: Int): Boolean |
Since adapter class is ready now. We will use ExpandableListView widget in xml file. Then, we will access this ExpandableListView using kotlin file and perform some operations on it.
6. Use ExpandableListView Widget in xml file
Open src/main/res/layout/activity_main.xml file and add below code into it.
<?xml version="1.0" encoding="utf-8"?> <LinearLayout 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/expandableListView" android:layout_width="match_parent" android:layout_height="match_parent" android:dividerHeight="0.5dp"> </ExpandableListView> </LinearLayout>
In activity_main.xml file, we have used ExpandableListView widget. This widget is responsible for providing hierarchy level view. Now, we will access this ExpandableListView using kotlin file and perform some actions on it.
7. Access ExpandableListView using Kotlin file
Open src/main/java/com.tutorialwing.expandablelistview/MainActivity.kt file and add below code into it.
package com.tutorialwing.expandablelistview import android.os.Bundle import android.support.v7.app.AppCompatActivity import android.view.View import android.widget.ExpandableListAdapter import android.widget.ExpandableListView import android.widget.Toast import java.util.ArrayList import java.util.HashMap class MainActivity : AppCompatActivity() { internal var expandableListView: ExpandableListView? = null internal var adapter: ExpandableListAdapter? = null internal var titleList: List<String> ? = null val data: HashMap<String, List<String>> get() { val listData = HashMap<String, List<String>>() val redmiMobiles = ArrayList<String>() redmiMobiles.add("Redmi Y2") redmiMobiles.add("Redmi S2") redmiMobiles.add("Redmi Note 5 Pro") redmiMobiles.add("Redmi Note 5") redmiMobiles.add("Redmi 5 Plus") redmiMobiles.add("Redmi Y1") redmiMobiles.add("Redmi 3S Plus") val micromaxMobiles = ArrayList<String>() micromaxMobiles.add("Micromax Bharat Go") micromaxMobiles.add("Micromax Bharat 5 Pro") micromaxMobiles.add("Micromax Bharat 5") micromaxMobiles.add("Micromax Canvas 1") micromaxMobiles.add("Micromax Dual 5") val appleMobiles = ArrayList<String>() appleMobiles.add("iPhone 8") appleMobiles.add("iPhone 8 Plus") appleMobiles.add("iPhone X") appleMobiles.add("iPhone 7 Plus") appleMobiles.add("iPhone 7") appleMobiles.add("iPhone 6 Plus") val samsungMobiles = ArrayList<String>() samsungMobiles.add("Samsung Galaxy S9+") samsungMobiles.add("Samsung Galaxy Note 7") samsungMobiles.add("Samsung Galaxy Note 5 Dual") samsungMobiles.add("Samsung Galaxy S8") samsungMobiles.add("Samsung Galaxy A8") samsungMobiles.add("Samsung Galaxy Note 4") listData["Redmi"] = redmiMobiles listData["Micromax"] = micromaxMobiles listData["Apple"] = appleMobiles listData["Samsung"] = samsungMobiles return listData } override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) expandableListView = findViewById(R.id.expandableListView) if (expandableListView != null) { val listData = data titleList = ArrayList(listData.keys) adapter = CustomExpandableListAdapter(this, titleList as ArrayList<String>, listData) expandableListView!!.setAdapter(adapter) expandableListView!!.setOnGroupExpandListener { groupPosition -> Toast.makeText(applicationContext, (titleList as ArrayList<String>)[groupPosition] + " List Expanded.", Toast.LENGTH_SHORT).show() } expandableListView!!.setOnGroupCollapseListener { groupPosition -> Toast.makeText(applicationContext, (titleList as ArrayList<String>)[groupPosition] + " List Collapsed.", Toast.LENGTH_SHORT).show() } expandableListView!!.setOnChildClickListener { parent, v, groupPosition, childPosition, id -> Toast.makeText(applicationContext, "Clicked: " + (titleList as ArrayList<String>)[groupPosition] + " -> " + listData[(titleList as ArrayList<String>)[groupPosition]]!!.get(childPosition), Toast.LENGTH_SHORT).show() false } } } }
Here, we have accessed expandableListView using kotlin file i.e. In MainActivity.kt file. Then, an instance of CustomExpandableListAdapter class has been created. Then, this adapter class is set as an adapter of expandableListView.
After that we have set some listeners (GroupExpandListener, GroupCollapseListener and ChildClickListener) to expandableListView.
8. Setting Listeners in expandableListView
You can set different listeners in expandableListView –
- (i) Group Expand Listener
- (ii) Group Collapse Listener
- (iii) Child Click Listener
8.1 Setting GroupExpandListener in ExpandableListView
We need group expand listener to perform the task whenever any group is expanded. You can set group expand listener in expandableListView using kotin as below –
expandableListView!!.setOnGroupExpandListener { groupPosition -> Toast.makeText(applicationContext, (titleList as ArrayList<String>)[groupPosition] + " List Expanded.", Toast.LENGTH_SHORT).show() }
Here, we are showing a toast message whenever any group is expanded and this method is called.
You can also perform the same task by overriding onGroupExpanded(groupPosition: Int) method in adapter class of ExpandableListView. For example, in given CustomExpandableListAdapter.kt class, you can override onGroupExpanded(groupPosition: Int) method as below –
override fun onGroupExpanded(groupPosition: Int) { Toast.makeText(context, (titleList as ArrayList<String>)[groupPosition] + " List Expanded.", Toast.LENGTH_SHORT).show() }
Here, we are also showing a toast message whenever this method is called.
8.2 Setting GroupCollapsedListener in ExpandableListView
We need groupCollapsed listener to perform some operations whenever any group is collapsed. You can set group collapsed listener in expandableListView using kotlin as shown below –
expandableListView!!.setOnGroupCollapseListener { groupPosition -> Toast.makeText(applicationContext, (titleList as ArrayList<String>)[groupPosition] + " List Collapsed.", Toast.LENGTH_SHORT).show() }
Or, you can perform same task by overriding onGroupCollapsed(groupPosition: Int) method in adapter class of expandableListView. For example, in given CustomExpandableListAdapter.kt class, you can override onGroupCollapsed(groupPosition: Int) method as below –
override fun onGroupCollapsed(groupPosition: Int) { Toast.makeText(context, (titleList as ArrayList<String>)[groupPosition] + " List Collapsed.", Toast.LENGTH_SHORT).show() }
8.3 Setting Child Click Listener in ExpandableListView
We need child click listener in expandableListView to perform some operations when any child item is clicked. You can set child click listener in expandableListView using kotlin as shown below –
expandableListView!!.setOnChildClickListener { parent, v, groupPosition, childPosition, id -> Toast.makeText(applicationContext, "Clicked: " + (titleList as ArrayList<String>)[groupPosition] + " -> " + listData[(titleList as ArrayList<String>)[groupPosition]]!!.get(childPosition), Toast.LENGTH_SHORT).show() false }
Here, we are also showing toast message whenever any child item is clicked.
Since AndroidManifest.xml file is very important in any android application, we are also going to see the content inside this file.
AndroidManifest.xml file
Code inside main/AndroidManifest.xml file is as below.
<?xml version="1.0" encoding="utf-8"?> <manifest package="com.tutorialwing.expandablelistview" xmlns:android="http://schemas.android.com/apk/res/android"> <application android:allowBackup="true" android:icon="@mipmap/ic_launcher" android:label="@string/app_name" android:roundIcon="@mipmap/ic_launcher_round" android:supportsRtl="true" android:theme="@style/AppTheme"> <activity android:name=".MainActivity"> <intent-filter> <action android:name="android.intent.action.MAIN"/> <category android:name="android.intent.category.LAUNCHER"/> </intent-filter> </activity> </application> </manifest>
When we run the program, we will get output as shown above.
That’s end of our tutorial on Android ExpandableListView using Kotlin.