Using ExpandableListView in Android with Kotlin
Overview of ExpandableListView
ExpandableListView is an Android widget that provides a way to group list data into categories, each of which can be expanded to show or collapsed to hide its children. This is particularly useful for displaying complex lists with multiple levels of data.
Setting Up the Project
To get started, you need to set up an Android project in Android Studio. Follow these steps:
- Open Android Studio and create a new project.
- Select “Empty Activity” and click “Next”.
- Name your project and set the language to “Kotlin”.
- Click “Finish” to create the project.
Creating the Layout
Next, you’l.l need to create the layout for your ExpandableListView. Open the activity_main.xml file and add the
following XML code:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<ExpandableListView
android:id="@+id/expandable_list_view"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</RelativeLayout>
This layout simply includes an ExpandableListView that takes up the entire screen.
Setting Up the Data
To populate the ExpandableListView, you need to define the data. Typically, this data is structured in the form of
a HashMap where each key represents a group and each value is a list of children for that group.
Create a new file called DataProvider.kt and add the following code:
object DataProvider {
fun getData(): HashMap<String, List<String>> {
val expandableListDetail = HashMap<String, List<String>>()
val group1 = listOf("Child 1", "Child 2")
val group2 = listOf("Child 3", "Child 4")
expandableListDetail["Group 1"] = group1
expandableListDetail["Group 2"] = group2
return expandableListDetail
}
}
Creating the Adapter
Next, create a custom adapter to bridge the data and the ExpandableListView. Create a new file
called CustomExpandableListAdapter.kt and add the following code:
import android.content.Context
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.BaseExpandableListAdapter
import android.widget.TextView
class CustomExpandableListAdapter(
private val context: Context,
private val expandableListTitle: List<String>,
private val expandableListDetail: HashMap<String, List<String>>
) : BaseExpandableListAdapter() {
override fun getChild(listPosition: Int, expandedListPosition: Int): Any {
return this.expandableListDetail[this.expandableListTitle[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(android.R.layout.simple_list_item_1, null)
}
val expandedListTextView = convertView!!.findViewById<TextView>(android.R.id.text1)
expandedListTextView.text = expandedListText
return convertView
}
override fun getChildrenCount(listPosition: Int): Int {
return this.expandableListDetail[this.expandableListTitle[listPosition]]!!.size
}
override fun getGroup(listPosition: Int): Any {
return this.expandableListTitle[listPosition]
}
override fun getGroupCount(): Int {
return this.expandableListTitle.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(android.R.layout.simple_expandable_list_item_1, null)
}
val listTitleTextView = convertView!!.findViewById<TextView>(android.R.id.text1)
listTitleTextView.text = listTitle
return convertView
}
override fun hasStableIds(): Boolean {
return false
}
override fun isChildSelectable(listPosition: Int, expandedListPosition: Int): Boolean {
return true
}
}
Implementing ExpandableListView
Now, let’s put everything together in the MainActivity. Open MainActivity.kt and add the following code:
import android.os.Bundle
import androidx.appcompat.app.AppCompatActivity
import kotlinx.android.synthetic.main.activity_main.*
class MainActivity : AppCompatActivity() {
private lateinit var expandableListAdapter: CustomExpandableListAdapter
private lateinit var expandableListTitle: List<String>
private lateinit var expandableListDetail: HashMap<String, List<String>>
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
expandableListDetail = DataProvider.getData()
expandableListTitle = ArrayList(expandableListDetail.keys)
expandableListAdapter = CustomExpandableListAdapter(this, expandableListTitle, expandableListDetail)
expandableListView.setAdapter(expandableListAdapter)
}
}
This code initializes the ExpandableListView, sets the adapter, and populates it with data.
Handling Click Events
To handle click events on group and child items, add the following code to MainActivity:
expandableListView.setOnGroupExpandListener { groupPosition ->
// Handle group expand event
}
expandableListView.setOnGroupCollapseListener { groupPosition ->
// Handle group collapse event
}
expandableListView.setOnChildClickListener { parent, v, groupPosition, childPosition, id ->
// Handle child click event
false
}
Conclusion
ExpandableListView is a powerful widget in Android that allows you to display data in a hierarchical format.
By following this guide, you should be able to implement an ExpandableListView in your Android application, customize
it with your own data, and handle various events to create a dynamic user experience.