iT邦幫忙

第 12 屆 iThome 鐵人賽

DAY 28
0
Mobile Development

Android Kotlin開發 -小嫩雞的30篇精選筆記系列 第 28

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.


上一篇
Android x Kotlin : 簡易實作第一堂-滾動式選單NumberPicker
下一篇
Android x Kotlin : 簡易實作第一堂-自定義customView與在xml中設定屬性預設值
系列文
Android Kotlin開發 -小嫩雞的30篇精選筆記30

尚未有邦友留言

立即登入留言