Android ExpandableListView使用小結(jié)(一)

ExpandableListView 是什么吏廉?

官方給出的解釋是:
A view that shows items in a vertically scrolling two-level list. This differs from the ListView by allowing two levels: groups which can individually be expanded to show its children. The items come from the ExpandableListAdapter associated with this view.

簡(jiǎn)單翻譯一下就是:
一種用于垂直滾動(dòng)展示兩級(jí)列表的視圖望几,和 ListView 的不同之處就是它可以展示兩級(jí)列表囤官,分組可以單獨(dú)展開顯示子選項(xiàng)。這些選項(xiàng)的數(shù)據(jù)是通過 ExpandableListAdapter 關(guān)聯(lián)的堡妒。

這個(gè) ExpandableListAdapter 又是什么呢?和 ListView 使用的 BaseAdapter 差不多,都是用來給 View 提供數(shù)據(jù)析桥、 實(shí)例化子布局的。實(shí)際使用的時(shí)候?qū)崿F(xiàn)這個(gè)接口就可以了艰垂。

了解了這么多泡仗,我們來親自實(shí)戰(zhàn)一下。

  1. 定義布局文件猜憎,指定必要的屬性娩怎,其他的先不修改。
<ExpandableListView
        android:id="@+id/expand_list"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />
  1. 定義要顯示的數(shù)據(jù)胰柑,分組的數(shù)據(jù)是個(gè)一維數(shù)組截亦,子列表的數(shù)據(jù)是個(gè)二維數(shù)組。這個(gè)好理解吧柬讨,子列表依附于某個(gè)分組魁巩,本身還有索引,當(dāng)然要定義成二維的姐浮。
 public String[] groupStrings = {"西游記", "水滸傳", "三國演義", "紅樓夢(mèng)"};
    public String[][] childStrings = {
            {"唐三藏", "孫悟空", "豬八戒", "沙和尚"},
            {"宋江", "林沖", "李逵", "魯智深"},
            {"曹操", "劉備", "孫權(quán)", "諸葛亮", "周瑜"},
            {"賈寶玉", "林黛玉", "薛寶釵", "王熙鳳"}
    };
  1. 定義分組的視圖和子選項(xiàng)的視圖谷遂,這里就用最簡(jiǎn)單的 TextView,顯示文字?jǐn)?shù)據(jù)就可以了卖鲤。
    下面是分組的視圖肾扰,因?yàn)榉纸M項(xiàng)左邊要顯示 Indicator 的緣故,所以這里加上了給 TextView 加上了內(nèi)邊距蛋逾。子選項(xiàng)的視圖也是一個(gè) TextView集晚,比較簡(jiǎn)單就不貼代碼了。
<TextView
    android:id="@+id/label_expand_group"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_gravity="center_vertical"
    android:background="@android:color/holo_blue_light"
    android:paddingLeft="20dp"
    android:textColor="@android:color/white"
    android:textSize="20sp" />
  1. 自定義適配器区匣,需要繼承 BaseExpandableListAdapter 抽象類偷拔,重寫相關(guān)的方法,代碼中沒貼出來的提供默認(rèn)實(shí)現(xiàn)就好了。
    //        獲取分組的個(gè)數(shù)
    @Override
    public int getGroupCount() {
        return groupStrings.length;
    }

    //        獲取指定分組中的子選項(xiàng)的個(gè)數(shù)
    @Override
    public int getChildrenCount(int groupPosition) {
        return childStrings[groupPosition].length;
    }

    //        獲取指定的分組數(shù)據(jù)
    @Override
    public Object getGroup(int groupPosition) {
        return groupStrings[groupPosition];
    }

    //        獲取指定分組中的指定子選項(xiàng)數(shù)據(jù)
    @Override
    public Object getChild(int groupPosition, int childPosition) {
        return childStrings[groupPosition][childPosition];
    }

    //        獲取指定分組的ID, 這個(gè)ID必須是唯一的
    @Override
    public long getGroupId(int groupPosition) {
        return groupPosition;
    }

    //        獲取子選項(xiàng)的ID, 這個(gè)ID必須是唯一的
    @Override
    public long getChildId(int groupPosition, int childPosition) {
        return childPosition;
    }

    //        分組和子選項(xiàng)是否持有穩(wěn)定的ID, 就是說底層數(shù)據(jù)的改變會(huì)不會(huì)影響到它們莲绰。
    @Override
    public boolean hasStableIds() {
        return true;
    }
    //        獲取顯示指定分組的視圖
    @Override
    public View getGroupView(int groupPosition, boolean isExpanded, View convertView, ViewGroup parent) {
        GroupViewHolder groupViewHolder;
        if (convertView == null) {
            convertView = LayoutInflater.from(MainActivity.this).inflate(R.layout.item_expand_group, parent, false);
            groupViewHolder = new GroupViewHolder();
            groupViewHolder.tvTitle = (TextView) convertView.findViewById(R.id.label_expand_group);
            convertView.setTag(groupViewHolder);
        } else {
            groupViewHolder = (GroupViewHolder) convertView.getTag();
        }
        groupViewHolder.tvTitle.setText(groupStrings[groupPosition]);
        return convertView;
    }

    //        獲取顯示指定分組中的指定子選項(xiàng)的視圖
    @Override
    public View getChildView(int groupPosition, int childPosition, boolean isLastChild, View convertView, ViewGroup parent) {
        ChildViewHolder childViewHolder;
        if (convertView == null) {
            convertView = LayoutInflater.from(MainActivity.this).inflate(R.layout.item_expand_child, parent, false);
            childViewHolder = new ChildViewHolder();
            childViewHolder.tvTitle = (TextView) convertView.findViewById(R.id.label_expand_child);
            convertView.setTag(childViewHolder);
        } else {
            childViewHolder = (ChildViewHolder) convertView.getTag();
        }
        childViewHolder.tvTitle.setText(childStrings[groupPosition][childPosition]);
        return convertView;
    }

    //        指定位置上的子元素是否可選中
    @Override
    public boolean isChildSelectable(int groupPosition, int childPosition) {
        return true;
    } 

    static class GroupViewHolder {
        TextView tvTitle;
    }
    static class ChildViewHolder {
        TextView tvTitle;
}
  1. 為 ExpandableListView 設(shè)置適配器呀欺旧,一行代碼搞定!
expandableListView.setAdapter(new MyExpandableListAdapter());
  1. 對(duì)于處理 Item 的點(diǎn)擊事件蛤签,還是要設(shè)置監(jiān)聽器辞友,常用的有這幾類:
  • setOnChildClickListener
  • setOnGroupClickListener
  • setOnGroupCollapseListener
  • setOnGroupExpandListener
    通過方法名我們就能知道各自的用途,它們分別設(shè)置單擊子選項(xiàng)震肮、單擊分組項(xiàng)称龙、分組合并、分組展開的監(jiān)聽器戳晌。
//        設(shè)置分組項(xiàng)的點(diǎn)擊監(jiān)聽事件
expandableListView.setOnGroupClickListener(new ExpandableListView.OnGroupClickListener() {
    @Override
    public boolean onGroupClick(ExpandableListView expandableListView, View view, int i, long l) {
        Toast.makeText(getApplicationContext(), groupStrings[i], Toast.LENGTH_SHORT).show();
        // 請(qǐng)務(wù)必返回 false鲫尊,否則分組不會(huì)展開
        return false;
    }
//        設(shè)置子選項(xiàng)點(diǎn)擊監(jiān)聽事件
expandableListView.setOnChildClickListener(new ExpandableListView.OnChildClickListener() {
    @Override
    public boolean onChildClick(ExpandableListView parent, View v, int groupPosition, int childPosition, long id) {
        Toast.makeText(getApplicationContext(), childStrings[groupPosition][childPosition], Toast.LENGTHshow();
        return true;
    }
});

到現(xiàn)在基本上完成了,我們來看一下運(yùn)行效果~~

效果圖

在下篇文章Android ExpandableListView使用小結(jié)(二)中沦偎,我會(huì)分享有關(guān) ExpandableListView 的 Indicator(指示器)的使用疫向,歡迎各位圍觀~

Demo 地址:點(diǎn)我飛往 GitHub~

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市扛施,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌屹篓,老刑警劉巖疙渣,帶你破解...
    沈念sama閱讀 206,602評(píng)論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異堆巧,居然都是意外死亡妄荔,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,442評(píng)論 2 382
  • 文/潘曉璐 我一進(jìn)店門谍肤,熙熙樓的掌柜王于貴愁眉苦臉地迎上來啦租,“玉大人,你說我怎么就攤上這事荒揣∨窠牵” “怎么了?”我有些...
    開封第一講書人閱讀 152,878評(píng)論 0 344
  • 文/不壞的土叔 我叫張陵系任,是天一觀的道長(zhǎng)恳蹲。 經(jīng)常有香客問我,道長(zhǎng)俩滥,這世上最難降的妖魔是什么嘉蕾? 我笑而不...
    開封第一講書人閱讀 55,306評(píng)論 1 279
  • 正文 為了忘掉前任,我火速辦了婚禮霜旧,結(jié)果婚禮上错忱,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好以清,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,330評(píng)論 5 373
  • 文/花漫 我一把揭開白布儿普。 她就那樣靜靜地躺著,像睡著了一般玖媚。 火紅的嫁衣襯著肌膚如雪箕肃。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,071評(píng)論 1 285
  • 那天今魔,我揣著相機(jī)與錄音勺像,去河邊找鬼。 笑死错森,一個(gè)胖子當(dāng)著我的面吹牛吟宦,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播涩维,決...
    沈念sama閱讀 38,382評(píng)論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼殃姓,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來了瓦阐?” 一聲冷哼從身側(cè)響起蜗侈,我...
    開封第一講書人閱讀 37,006評(píng)論 0 259
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎睡蟋,沒想到半個(gè)月后踏幻,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,512評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡戳杀,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,965評(píng)論 2 325
  • 正文 我和宋清朗相戀三年该面,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片信卡。...
    茶點(diǎn)故事閱讀 38,094評(píng)論 1 333
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡隔缀,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出傍菇,到底是詐尸還是另有隱情猾瘸,我是刑警寧澤,帶...
    沈念sama閱讀 33,732評(píng)論 4 323
  • 正文 年R本政府宣布丢习,位于F島的核電站须妻,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏泛领。R本人自食惡果不足惜荒吏,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,283評(píng)論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望渊鞋。 院中可真熱鬧绰更,春花似錦瞧挤、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,286評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至徐钠,卻和暖如春癌刽,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背尝丐。 一陣腳步聲響...
    開封第一講書人閱讀 31,512評(píng)論 1 262
  • 我被黑心中介騙來泰國打工显拜, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人爹袁。 一個(gè)月前我還...
    沈念sama閱讀 45,536評(píng)論 2 354
  • 正文 我出身青樓远荠,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國和親失息。 傳聞我的和親對(duì)象是個(gè)殘疾皇子譬淳,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,828評(píng)論 2 345

推薦閱讀更多精彩內(nèi)容

  • 內(nèi)容抽屜菜單ListViewWebViewSwitchButton按鈕點(diǎn)贊按鈕進(jìn)度條TabLayout圖標(biāo)下拉刷新...
    皇小弟閱讀 46,708評(píng)論 22 664
  • Android UI相關(guān)開源項(xiàng)目庫匯總OpenDigg 抽屜菜單MaterialDrawer ★7337 - 安卓...
    黃海佳閱讀 8,690評(píng)論 3 77
  • 親愛的,同你說幾句話盹兢。 今天中午聽boss分析人員性格動(dòng)態(tài)邻梆,她同我說:“……他們畢竟是北京人,本地北京人還是有些高...
    嫏嬛素素閱讀 197評(píng)論 0 0
  • 天一閣藏在心里很久了绎秒。 一個(gè)喜歡讀兩本書的人浦妄,總會(huì)有圖書館閱覽室的圖景在他的眉間心上不時(shí)搖曳。何況這樣一座現(xiàn)存年代...
    鉛筆芒種閱讀 632評(píng)論 0 2
  • 重看《新白娘子傳奇》替裆,竟然潸然淚下校辩,大致是懂了里面的情感罷窘问。
    RyanFZH閱讀 267評(píng)論 0 2