ExpandableListView 是一個類似于QQ聯(lián)系人那樣的分組的 listView
效果如圖,這是簡單實現(xiàn)背镇,復(fù)雜點的話完全可以添加圖標(biāo)頭像什么的咬展,為什么說優(yōu)雅呢?因為我要用的時候發(fā)現(xiàn)其他的博客有的是simple適配器瞒斩,有的是匿名內(nèi)部類破婆,等等,這實現(xiàn)起來固然快胸囱,但是后期擴(kuò)展比較麻煩祷舀,維護(hù)也麻煩,點都不清真烹笔。
![效果圖](http://ww1.sinaimg.cn/mw690/b5ad68f7gy1ffxqfinlauj20u01hcq3y.jpg)
我的代碼顯示這么簡單的內(nèi)容會顯得有點多裳扯,但是我的目的絕不是說就只是為了告訴看官怎么實現(xiàn)二級list,我還希望告訴看官怎樣讓ExpandableListView具有擴(kuò)展性谤职,并且在需求增加的時候只需要做簡單的修改就行可以滿足增加的需求饰豺,所以還請有耐心的看下去
1. 準(zhǔn)備工作
我們的代碼量基本就集中在準(zhǔn)備工作了,到真正調(diào)用的時候就幾行代碼就搞定了柬帕。
1.1 創(chuàng)建布局文件
首先需要在 layout 目錄下創(chuàng)建兩個布局文件哟忍,分別是分組的組布局和分組下面的數(shù)據(jù)的布局,也就是截圖中的顯示銷售陷寝、主管、售后的布局和顯示張三其馏、王麻子的布局凤跑。
現(xiàn)在看看我創(chuàng)建的布局
item_group_exlist.xml·······這個就是顯示部門的布局
item_exlist.xml················這個是顯示員工的布局
item_group_exlist.xml
<?xml version="1.0" encoding="utf-8"?>
<!-- ExpandableList的父級菜單布局 -->
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
android:paddingTop="8dp"
android:paddingBottom="8dp"
android:paddingLeft="36dp"
android:textSize="20sp"
android:textColor="#000000"
android:id="@+id/view_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</LinearLayout>
布局中的 paddingLeft 是為了防止字體和左邊的圖標(biāo)重合。
item_exlist.xml
<?xml version="1.0" encoding="utf-8"?>
<!-- expandableList 的子級條目布局 -->
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:paddingTop="8dp"
android:paddingBottom="8dp"
android:paddingLeft="36dp"
android:textColor="#000000"
android:id="@+id/view_content"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</LinearLayout>
OK叛复,這里布局就創(chuàng)建好了仔引,以后需要添加圖標(biāo)什么的也是在這個布局里添加
1.2 創(chuàng)建Bean文件
javaBean就是一個數(shù)據(jù)對象,用來裝載數(shù)據(jù)褐奥,可以set和get
這里需要創(chuàng)建兩個Java類咖耘。
GroupBean.java······這個是裝部門數(shù)據(jù)的,也就是父級數(shù)據(jù)
ItemBean.java···· ····這個是裝人員數(shù)據(jù)的撬码,也就是子級數(shù)據(jù)
GroupBean.java
package cc.jethro.expandablelisttest;
/**
* 部門數(shù)據(jù)bean
* Created by jethro on 2017/5/25.
*/
public class GroupBean {
private String title ; //部門名稱
/**
* @param title 部門名稱
*/
GroupBean(String title) {
this.title = title;
}
//獲取部門名稱
public String getTitle() {
return title;
}
//設(shè)置部門名稱
public void setTitle(String title) {
this.title = title;
}
}
ItemBean.java
/**
* 人員數(shù)據(jù)bean
* Created by jethro on 2017/5/25.
*/
public class ItemBean {
//人員姓名
private String content ;
ItemBean(String content) {
this.content = content;
}
public String getContent() {
return content;
}
public void setContent(String content) {
this.content = content;
}
}
好儿倒,這個時候準(zhǔn)備工作已經(jīng)做了一半了。
1.3 創(chuàng)建adapter適配器
適配器的作用就是把數(shù)據(jù)顯示出來,ExpandableList會在顯示數(shù)據(jù)的時候調(diào)用Adapter里面的方法來讀取數(shù)據(jù)夫否,當(dāng)然彻犁,我們的數(shù)據(jù)也會傳入到這個Adapter里面
我們的適配器將接收5個參數(shù),分別是context凰慈,父級和子級的布局汞幢,以及兩個裝有bean的LIst,一個是部門數(shù)據(jù)微谓,一個人員數(shù)據(jù)森篷。好,現(xiàn)在開始寫代碼
1.3.1 創(chuàng)建一個Java類豺型,實現(xiàn) ExpandableListAdapter 接口
![](http://ww1.sinaimg.cn/mw690/b5ad68f7gy1ffxsi7esqjj20kj08m3yo.jpg)
可以看到是一片紅線仲智,那是因為我們必須實現(xiàn) ExpandableListAdapter 接口里的方法,先鼠標(biāo)點一下紅線触创,按Alt+回車
![](http://ww1.sinaimg.cn/mw690/b5ad68f7gy1ffxslfai0pj20m804vdfw.jpg)
直接回車選第一個坎藐,出現(xiàn)如圖這么多方法
![](http://ww1.sinaimg.cn/mw690/b5ad68f7gy1ffxsmyze54j20au0gl3z2.jpg)
別怕,并不是每個方法都要我們?nèi)懞甙螅覀兿赛cOK岩馍,或者回車,然后再回車就可以看到AS自動幫我們聲明了這些方法抖韩。
![](http://ww1.sinaimg.cn/mw690/b5ad68f7gy1ffylh9agqij20lm0e8aad.jpg)
先聲明要使用到的變量
![](http://ww1.sinaimg.cn/mw690/b5ad68f7gy1ffylle5vacj20hp07pglq.jpg)
還記得我們剛才創(chuàng)建的兩個Bean類嗎蛀恩?就是GroupBean和ItemBean,現(xiàn)在我們要用到它茂浮,讓它發(fā)光發(fā)熱了双谆。
如果Java基礎(chǔ)不好的話,可能不會理解第一個變量的聲明席揽,我來解釋一下List<GroupBean> groupList;
List是一個存儲變量或者說對象的類顽馋,你可以用它來存任何類型的變量,但是我們這里只想讓它存儲我們的GroupBean變量幌羞,所以就在他的后面加一個<GroupBean>寸谜,這樣的話,如果你試圖往List里存其他的類型的變量就會報錯属桦,只能存儲GroupBean變量熊痴。
然后有的同學(xué)可能就會問了,為什么第二個變量childrenList
是限制為List而不是限制為ItemBean ?
容我畫張圖來解釋下這個數(shù)據(jù)結(jié)構(gòu)
![數(shù)據(jù)結(jié)構(gòu)圖](http://ww1.sinaimg.cn/large/b5ad68f7gy1ffymlvwbofj21660hsq3u.jpg)
看吧
groupList里面存儲了GroupBean,而GroupList類就是部門名稱屬性
childrenList里面存儲了List聂宾,List里存儲了ItemBean果善,ItemBean類就是人員姓名屬性。
左邊的一個GroupBean對應(yīng)著右邊的一個List系谐,我們后面會限制List只能存儲ItemBean類
好巾陕,數(shù)據(jù)結(jié)構(gòu)理清楚了,我們來處理數(shù)據(jù)。
1.3.2 寫一個構(gòu)造方法
ItemBean xiaoshou = new ItemBean("張三") ;
new后面的ItemBean()就是構(gòu)造方法惜论,之前寫的GroupBean里就有寫構(gòu)造方法许赃,要求傳入一個String類型的參數(shù),作為人員姓名馆类。
構(gòu)造方法代碼如圖混聊,方法名跟類名一樣
![](http://ww1.sinaimg.cn/large/b5ad68f7gy1ffywun09plj20m20elgmg.jpg)
構(gòu)造方法很簡單,就是把傳進(jìn)來的參數(shù)賦值給剛才我們申明的變量乾巧,因為他們名字一樣句喜,所以自有變量前面加一個this。
1.3.3 為適配器編寫讀取數(shù)據(jù)的代碼
請結(jié)合前面的數(shù)據(jù)結(jié)構(gòu)圖來看下面的代碼
找到getGroupCount()
方法沟于,修改它
![](http://ww1.sinaimg.cn/large/b5ad68f7gy1ffyx3nmq4rj20dn057t8p.jpg)
找到getChildrenCount()
方法咳胃,修改它
![](http://ww1.sinaimg.cn/large/b5ad68f7gy1ffyx5oryp3j20hs07qwep.jpg)
這個方法是讀取第X個部門有多少人的,方法有一個參數(shù)旷太,groupPosition
這個參數(shù)是表示第X個部門的展懈。然后方法里的第一行代碼就是從childrenList里讀取第X個List,然后把它賦值給左邊什么的itemList供璧。到第二行代碼了存崖,很簡單,就是返回itemList的大小睡毒。
這兩個方法就是讀取部門數(shù)據(jù)和人員信息數(shù)據(jù)的来惧,找到他們并修改
![](http://ww1.sinaimg.cn/large/b5ad68f7gy1ffyyv4mplmj20ie0d0wf5.jpg)
第一個方法是讀取部門數(shù)據(jù)的,它的參數(shù)就是要讀取第X個GroupBean演顾,我們從groupList里讀出來返回給ExpandableList
第二個方法是讀取人員數(shù)據(jù)的供搀,它的參數(shù)是第X組的第Y個人員,X是groupPosition钠至,Y是childPosition葛虐。我們就從childrenList里取出第X組數(shù)據(jù),然后從第X組數(shù)據(jù)里取出第Y條數(shù)據(jù)棉钧,把他返回給ExpandableList
1.3.4 設(shè)置布局和設(shè)置數(shù)據(jù)到屏幕上
這是設(shè)置部門布局和數(shù)據(jù)的代碼
![](http://ww1.sinaimg.cn/large/b5ad68f7gy1ffz0xeive5j20lo0e20tp.jpg)
就是三部曲挡闰,加載布局->讀取數(shù)據(jù)->設(shè)置數(shù)據(jù)到布局,這同樣適用于設(shè)置人員布局和數(shù)據(jù)掰盘,看代碼
![](http://ww1.sinaimg.cn/large/b5ad68f7gy1ffz0enialsj20mw0atwf3.jpg)
可以看到幾乎跟設(shè)置部門布局和數(shù)據(jù)的差不多,所以就不多做注釋了赞季。
![](http://ww1.sinaimg.cn/large/b5ad68f7gy1ffz0enialsj20mw0atwf3.jpg)
1.3.5 關(guān)于適配器的最后參數(shù)設(shè)置
![](http://ww1.sinaimg.cn/large/b5ad68f7gy1ffz0klcydfj20kf09tmxc.jpg)
想知道為什么愧捕?自己去查Google的API文檔。
2. 享受成功
準(zhǔn)備工作做完了申钩,我們創(chuàng)建好了布局次绘、數(shù)據(jù)對象(Bean)、適配器,現(xiàn)在邮偎,我們將使用他們來顯示我們的分組數(shù)據(jù)
2.1 在activity的布局文件中申明我們的ExpandableListView
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 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="cc.jethro.expandablelisttest.MainActivity">
<ExpandableListView
android:id="@+id/view_exlist"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</LinearLayout>
2.2 準(zhǔn)備好我們要顯示的數(shù)據(jù)
現(xiàn)在管跺,讓我們切回MainActivity,申明兩個變量
![](http://ww1.sinaimg.cn/large/b5ad68f7gy1ffz17xp8npj20fw065wer.jpg)
接著創(chuàng)建一個initData()方法禾进,我們在這個方法里填充數(shù)據(jù)
![](http://ww1.sinaimg.cn/large/b5ad68f7gy1ffz1dqhexij20b00fkq3i.jpg)
2.3 設(shè)置適配器
![](http://ww1.sinaimg.cn/large/b5ad68f7gy1ffz1qso5i6j20pb0elmy6.jpg)
3.0 編譯運行
![默認(rèn)不是展開的豁跑,是我點開的](http://ww1.sinaimg.cn/large/b5ad68f7gy1ffz1yhb627j20u01hc3zj.jpg)
正常顯示泻云,沒毛病
代碼寫下來有點大炮打蚊子的感覺艇拍,但是蚊子會變成灰機(jī),后面我會接著寫當(dāng)蚊子變成灰機(jī)的時候宠纯,怎么優(yōu)雅的去用大炮打灰機(jī)卸夕。
附上源碼地址
點擊進(jìn)入百度網(wǎng)盤下載