Android x Kotlin : 展开式列表ExpandableListView用法

简介

展开式的列表清单。
外部项目例如一般会员、忠诚会员...这些我们称为groupView,
每个group内的子项目群我们称为childView。

资料来源:台湾漫画基地

1.MyLevelPageData.kt

先写假资料

class MyLevelPageData{


    data class RenewQualificationGroup(
        val img:Int,
        val title:String,
        val subTitle:String,
        var isExpanded:Boolean,
        val childList: MutableList<RenewQualificationChild>
    )

    data class RenewQualificationChild(
        val title:String,
        val subTitle:String
    )

    //childView的资料
    var renewQualificationChildList = mutableListOf<RenewQualificationChild>(
        RenewQualificationChild("申请资格","一般会员会符合条件即可晋升忠诚会员"),
        RenewQualificationChild("晋升条件","累积消费达5,000元"),
        RenewQualificationChild("会籍效期","2年"),
        RenewQualificationChild("续会资格","於会籍期间累积消费达5,000元")
    )
    
    //GroupView的资料
    var renewQualificationGroupList = mutableListOf<RenewQualificationGroup>(
        RenewQualificationGroup(R.drawable.ic_mylevel_normal,"一般会员","",false,renewQualificationChildList),
        RenewQualificationGroup(R.drawable.ic_mylevel_loyalty,"忠诚会员","",false,renewQualificationChildList),
        RenewQualificationGroup(R.drawable.ic_mylevel_precreator,"准创作者会员","",false,renewQualificationChildList),
        RenewQualificationGroup(R.drawable.ic_mylevel_creator,"创作会员","",false,renewQualificationChildList)
    )
}

2.viewholer_renew_qualification_group.xml

定义GroupView的viewholder

<FrameLayout  xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="wrap_content">

    <androidx.constraintlayout.widget.ConstraintLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="@color/colorFFFFFF"
        android:id="@+id/vg_viewholder_renew_qualification_group">

        <ImageView
            android:id="@+id/icon"
            android:layout_width="24dp"
            android:layout_height="24dp"
            android:layout_marginStart="16dp"
            android:layout_marginTop="16dp"
            android:layout_marginBottom="16dp"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="parent"
            tools:srcCompat="@tools:sample/avatars" />

        <TextView
            android:id="@+id/tv_title_renew_qualification_group"
            android:layout_width="0dp"
            android:layout_height="57dp"
            android:layout_marginStart="16dp"
            android:layout_marginEnd="16dp"
            android:gravity="center_vertical"
            android:text="TextView"
            android:textColor="@color/color444444"
            android:textSize="16sp"
            app:layout_constraintEnd_toStartOf="@+id/tv_subtitle"
            app:layout_constraintStart_toEndOf="@+id/icon"
            app:layout_constraintTop_toTopOf="parent" />

        <ImageView
            android:id="@+id/imgv_show_child"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginEnd="16dp"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintTop_toTopOf="parent"
            app:srcCompat="@drawable/sl_angle_top_down" />

        <View
            android:id="@+id/view_spacing_line_viewholder_my_level_group"
            android:layout_width="0dp"
            android:layout_height="1dp"
            android:background="@color/coloreeeeee"
            app:layout_constraintBottom_toBottomOf="@+id/tv_title_renew_qualification_group"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="@+id/tv_title_renew_qualification_group" />

    </androidx.constraintlayout.widget.ConstraintLayout>

</FrameLayout>

3.viewholder_renew_qualification_child.xml

定义childView的viewholder

<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:background="@color/colorFFFFFF"
    android:orientation="vertical"
    android:id="@+id/vg_viewholder_renew_qualification_child">


    <TextView
        android:id="@+id/tv_title_renew_qualification_child"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:paddingTop="16dp"
        android:layout_marginStart="56dp"
        tools:text="申请资格"
        android:textColor="@color/color444444"
        android:textSize="16sp"
        android:textStyle="bold"
        app:layout_constraintBottom_toTopOf="@id/tv_subtitle_renew_qualification_child"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <TextView
        android:id="@+id/tv_subtitle_renew_qualification_child"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginEnd="8dp"
        android:paddingTop="8dp"
        android:paddingBottom="16dp"
        android:gravity="center"
        tools:text="一般会员会符合条件即可晋升忠诚会员"
        android:textColor="@color/coloraaaaaa"
        android:textSize="14sp"
        app:layout_constraintTop_toBottomOf="@id/tv_title_renew_qualification_child"
        app:layout_constraintStart_toStartOf="@id/tv_title_renew_qualification_child"/>

    <View
        android:id="@+id/view_spacing_line"
        android:layout_width="0dp"
        android:layout_height="1dp"
        android:background="@color/coloreeeeee"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="@+id/tv_title_renew_qualification_child" />

</androidx.constraintlayout.widget.ConstraintLayout>

4.RenewQualificationAdapter.kt

设定adapter。

class RenewQualificationAdapter(val context:Context): BaseExpandableListAdapter() {
    private var groupList = mutableListOf<MyLevelPageData.RenewQualificationGroup>()


    override fun getGroupCount(): Int = groupList.size

    override fun getChildrenCount(groupPosition: Int): Int = groupList[groupPosition].childList.size

    override fun getGroupId(groupPosition: Int): Long =
        groupList[groupPosition].hashCode().toLong()

    override fun getChildId(groupPosition: Int, childPosition: Int): Long =
        groupList[groupPosition].childList[childPosition].hashCode().toLong()

    override fun getGroup(groupPosition: Int): Any = groupList[groupPosition]

    override fun getChild(groupPosition: Int, childPosition: Int): Any =
        groupList[groupPosition].childList[childPosition]

    override fun isChildSelectable(groupPosition: Int, childPosition: Int): Boolean = true

    override fun hasStableIds(): Boolean = true

    override fun isEmpty(): Boolean = groupList.size == 0

    override fun onGroupExpanded(groupPosition: Int) {
        super.onGroupExpanded(groupPosition)
        groupList[groupPosition].isExpanded = true
    }

    override fun onGroupCollapsed(groupPosition: Int) {
        super.onGroupCollapsed(groupPosition)
        groupList[groupPosition].isExpanded =  false
    }


    //在这里绑定groupView的元件及资料
    override fun getGroupView(
        groupPosition: Int,
        isExpanded: Boolean,
        convertView: View?,
        parent: ViewGroup?
    ): View {
    
    
        val view = convertView ?: LayoutInflater.from(parent!!.context).inflate(R.layout.viewholder_my_level_group, null)
        val title = view.tv_title_my_level_group
        val subTitle = view.tv_subtitle
        val icon = view.icon
        val angle = view.imgv_show_child
        val spacingLine = view.view_spacing_line_viewholder_my_level_group

        title.text = groupList[groupPosition].title
        subTitle.text = groupList[groupPosition].subTitle
        icon.setImageResource(groupList[groupPosition].img)
        angle.isActivated = isExpanded

        //取掉最後一条分隔线
        if(title.text=="创作会员") spacingLine.visibility = View.GONE
        else spacingLine.visibility = View.VISIBLE

        return view
    }


    //在这里绑定childView的元件及资料
    override fun getChildView(
        groupPosition: Int,
        childPosition: Int,
        isLastChild: Boolean,
        convertView: View?,
        parent: ViewGroup?
    ): View {
        val view = convertView ?: LayoutInflater.from(parent!!.context).inflate(R.layout.viewholder_renew_qualification_child, null)
        val title = view.tv_title_renew_qualification_child
        val subTitle = view.tv_subtitle_renew_qualification_child

        title.text = groupList[groupPosition].childList[childPosition].title
        subTitle.text = groupList[groupPosition].childList[childPosition].subTitle

        //设定红字
        if(title.text=="续会资格") subTitle.setTextColor(context.resources.getColor(R.color.colorde452d))
        else subTitle.setTextColor(context.resources.getColor(R.color.coloraaaaaa))



        return view
    }


    fun updateList(groupList:MutableList<MyLevelPageData.RenewQualificationGroup>){
        this.groupList = groupList
    }

}

5. activity_main.kt

<ExpandableListView
        android:id="@+id/explv_renew_qualification"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:childDivider="@null"
        android:divider="@null"
        android:dividerHeight="0dp"
        android:groupIndicator="@null"
        android:transcriptMode="disabled"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@id/textView21"
        tools:listitem="@layout/viewholder_my_level_group"
        android:background="@color/colorf4f4f4"
        android:paddingBottom="12dp"/>

5.MainActivity.kt

        val adapter = RenewQualificationAdapter(context!!)
        val data = MyLevelPageData()
       
        adapter.updateList(data.renewQualificationGroupList)
        explv_renew_qualification.setAdapter(adapter)
        
        

Done.


<<:  第二十七章、燃烧吧!Three.js 小宇宙!(伍)

>>:  练功活动: 模拟案主!!

[Day 05] 当我~们同在一起在17在17 (k-means 理论篇)

前言 有一说一,表情辨识到底还是个分类任务。 如果我说有一种演算法可以在不需要标签的情况下自动帮我们...

Day18 Loops(Ⅴ)

今天再举一个for回圈的例子,找出1~100的偶数。 Ans:从一开始所以一开始int i=1,然後...

搞懂 P2P 技术 (2) - STUN x TURN x ICE

前言 上一篇介绍完中心化、去中心化、分布式网路以及 IPv4、NAT、NAT 类型,但我们依旧还有些...

Day22 火焰文字

火焰文字 教学原文参考:火焰文字 这篇文章会介绍在 GIMP 里使用涂抹工具、渐层映对、文字...等...

20.MYSQL XOR指令

XOR相较前面的指令,是比较难懂一点,他的意思是两侧条件有一边为1,就回传1,否则都回传0 ...