效果图

只能实现两层折叠。
image.png

属性简单介绍

  1. divider :父布局之间的分割线样式
  2. childDivider :子布局之间分割样式
  3. dividerHeight :用于设置分割线的高度
  4. childIndicator :用于设置子布局前显示的图标,不设置的话默认是没有图标的
  5. groupIndicator :设置父布局前显示的图标
  6. indicatorLeft/indicatorStart:默认图标距左侧距离
  7. indicatorRight/indicatorEnd :默认图标距右侧距离

使用详解

  1. 主界面

    1. <?xml version="1.0" encoding="utf-8"?>
    2. <androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    3. android:layout_width="match_parent"
    4. android:layout_height="match_parent">
    5. <ExpandableListView
    6. android:id="@+id/elvExpandList"
    7. android:layout_width="match_parent"
    8. android:layout_height="match_parent"
    9. android:groupIndicator="@null"/>
    10. </androidx.constraintlayout.widget.ConstraintLayout>
  2. activity

    1. class ExpandActivity: AppCompatActivity(R.layout.activity_expand) {
    2. override fun onCreate(savedInstanceState: Bundle?) {
    3. super.onCreate(savedInstanceState)
    4. initData()
    5. }
    6. lateinit var adapter: ExpandAdapter
    7. private fun initData() {
    8. val list = ArrayList<Contact>()
    9. var contact: Contact
    10. for (i in 0..8){
    11. contact = Contact("朋友$i",
    12. arrayListOf(
    13. Person("张三","123658956987"),
    14. Person("李四","123658956987"),
    15. Person("王五","123658956987")
    16. ))
    17. list.add(contact)
    18. }
    19. adapter = ExpandAdapter(this,list)
    20. elvExpandList.setAdapter(adapter)
    21. //默认展开第几个
    22. elvExpandList.expandGroup(3)
    23. //子布局点击
    24. elvExpandList.setOnChildClickListener { parent, v, groupPosition, childPosition, id ->
    25. Toast.makeText(this, "${list[groupPosition].list[childPosition].name}", Toast.LENGTH_SHORT).show()
    26. true
    27. }
    28. }
    29. }
  3. bean ```kotlin data class Contact( var title: String?, var list: List )

data class Person(var name: String?, var phone: String?)

  1. 4. adpter
  2. ```kotlin
  3. class ExpandAdapter(val context: Context, private val list: List<Contact>) :
  4. BaseExpandableListAdapter() {
  5. var layoutInflater: LayoutInflater = LayoutInflater.from(context)
  6. override fun getGroupCount(): Int = list.size
  7. override fun getChildrenCount(groupPosition: Int): Int = list[groupPosition].list.size
  8. override fun getGroup(groupPosition: Int): Any {
  9. return list[groupPosition]
  10. }
  11. override fun getChild(groupPosition: Int, childPosition: Int): Any {
  12. return list[groupPosition].list[childPosition]
  13. }
  14. override fun getGroupId(groupPosition: Int): Long {
  15. return groupPosition.toLong()
  16. }
  17. override fun getChildId(groupPosition: Int, childPosition: Int): Long {
  18. return childPosition.toLong()
  19. }
  20. override fun hasStableIds(): Boolean = false
  21. override fun getGroupView(
  22. groupPosition: Int,
  23. isExpanded: Boolean,
  24. convertView: View?,
  25. parent: ViewGroup?
  26. ): View {
  27. var convertView = convertView
  28. val holder: GroupViewHolder
  29. if (convertView == null) {
  30. convertView = layoutInflater.inflate(R.layout.item_expand_group, parent, false)
  31. holder = GroupViewHolder(convertView)
  32. convertView.tag = holder
  33. } else {
  34. holder = convertView.tag as GroupViewHolder
  35. }
  36. val groupData = list[groupPosition]
  37. holder.tvTitle.text = groupData.title
  38. holder.ivArrow.setImageResource(if (isExpanded) R.drawable.arrow_down else R.drawable.arrow_right)
  39. return convertView!!
  40. }
  41. override fun getChildView(
  42. groupPosition: Int,
  43. childPosition: Int,
  44. isLastChild: Boolean,
  45. convertView: View?,
  46. parent: ViewGroup?
  47. ): View {
  48. var convertView = convertView
  49. val holder: ChildViewHolder
  50. if (convertView == null) {
  51. convertView = layoutInflater.inflate(R.layout.item_expand_child, parent, false)
  52. holder = ChildViewHolder(convertView!!)
  53. convertView.tag = holder
  54. } else {
  55. holder = convertView.tag as ChildViewHolder
  56. }
  57. val childData = list[groupPosition].list[childPosition]
  58. holder.tvName.text = childData.name
  59. holder.tvMoblie.text = childData.phone
  60. return convertView
  61. }
  62. //子项是否可选中,如果要设置子项的点击事件,需要返回true
  63. override fun isChildSelectable(groupPosition: Int, childPosition: Int): Boolean = true
  64. /* internal class TestViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
  65. var tvTitle: TextView = itemView.findViewById(R.id.tvItemExpandGroupTitle)
  66. }*/
  67. class GroupViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
  68. var tvTitle: TextView = itemView.findViewById<TextView>(R.id.tvItemExpandGroupTitle)
  69. var ivArrow: ImageView = itemView.findViewById<ImageView>(R.id.ivExpandGroupArrow)
  70. }
  71. class ChildViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
  72. var tvName = itemView.findViewById<TextView>(R.id.tvItemExpandChildName)
  73. var tvMoblie = itemView.findViewById<TextView>(R.id.tvItemExpandChildPhone)
  74. }
  75. }
  1. 外层 Item 布局

    1. <?xml version="1.0" encoding="utf-8"?>
    2. <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    3. android:layout_width="match_parent"
    4. android:layout_height="50dp"
    5. android:paddingHorizontal="15dp">
    6. <TextView
    7. android:id="@+id/tvItemExpandGroupTitle"
    8. android:layout_width="wrap_content"
    9. android:layout_height="wrap_content"
    10. android:text="分组"
    11. android:layout_centerVertical="true"/>
    12. <ImageView
    13. android:id="@+id/ivExpandGroupArrow"
    14. android:layout_width="wrap_content"
    15. android:layout_height="wrap_content"
    16. android:src="@drawable/arrow_right"
    17. android:layout_centerVertical="true"
    18. android:layout_alignParentRight="true"/>
    19. </RelativeLayout>
  2. 内层 item 布局

    1. <?xml version="1.0" encoding="utf-8"?>
    2. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    3. android:orientation="horizontal"
    4. android:layout_width="match_parent"
    5. android:layout_height="40dp"
    6. android:background="@color/colorAccent">
    7. <TextView
    8. android:id="@+id/tvItemExpandChildName"
    9. android:layout_width="wrap_content"
    10. android:layout_height="wrap_content"
    11. android:text="@string/app_name"
    12. android:layout_gravity="center_vertical"
    13. android:layout_marginStart="50dp"
    14. android:textColor="@color/white"/>
    15. <TextView
    16. android:id="@+id/tvItemExpandChildPhone"
    17. android:layout_width="wrap_content"
    18. android:layout_height="wrap_content"
    19. android:text="@string/app_name"
    20. android:layout_gravity="center_vertical"
    21. android:layout_marginStart="20dp"
    22. android:textColor="@color/white"/>
    23. </LinearLayout>

    参考

    ExpandableListView
    ExpandableListView使用方法详解
    ExpanableListView