關於Android 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.
簡單翻譯一下就是:一種用於垂直滾動展示兩級列表的檢視,和 ListView 的不同之處就是它可以展示兩級列表,分組可以單獨展開顯示子選項。這些選項的資料是通過 ExpandableListAdapter 關聯的。
這個 ExpandableListAdapter 又是什麼呢?和 ListView 使用的 BaseAdapter 差不多,都是用來給 View 提供資料、 例項化子佈局的。實際使用的時候實現這個介面就可以了。
瞭解了這麼多,我們來親自實戰一下。
- 定義佈局檔案,指定必要的屬性,其他的先不修改。
<ExpandableListView android:id="@+id/expand_list" android:layout_width="match_parent" android:layout_height="match_parent" /> 複製程式碼
- 定義要顯示的資料,分組的資料是個一維陣列,子列表的資料是個二維陣列。這個好理解吧,子列表依附於某個分組,本身還有索引,當然要定義成二維的。
public String[] groupStrings = {"西遊記", "水滸傳", "三國演義", "紅樓夢"}; public String[][] childStrings = { {"唐三藏", "孫悟空", "豬八戒", "沙和尚"}, {"宋江", "林沖", "李逵", "魯智深"}, {"曹操", "劉備", "孫權", "諸葛亮", "周瑜"}, {"賈寶玉", "林黛玉", "薛寶釵", "王熙鳳"} }; 複製程式碼
- 定義分組的檢視和子選項的檢視,這裡就用最簡單的 TextView,顯示文字資料就可以了。 下面是分組的檢視,因為分組項左邊要顯示 Indicator 的緣故,所以這裡加上了給 TextView 加上了內邊距。子選項的檢視也是一個 TextView,比較簡單就不貼程式碼了。
<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" /> 複製程式碼
- 自定義介面卡,需要繼承 BaseExpandableListAdapter 抽象類,重寫相關的方法,程式碼中沒貼出來的提供預設實現就好了。
//獲取分組的個數 @Override public int getGroupCount() { return groupStrings.length; } //獲取指定分組中的子選項的個數 @Override public int getChildrenCount(int groupPosition) { return childStrings[groupPosition].length; } //獲取指定的分組資料 @Override public Object getGroup(int groupPosition) { return groupStrings[groupPosition]; } //獲取指定分組中的指定子選項資料 @Override public Object getChild(int groupPosition, int childPosition) { return childStrings[groupPosition][childPosition]; } //獲取指定分組的ID, 這個ID必須是唯一的 @Override public long getGroupId(int groupPosition) { return groupPosition; } //獲取子選項的ID, 這個ID必須是唯一的 @Override public long getChildId(int groupPosition, int childPosition) { return childPosition; } //分組和子選項是否持有穩定的ID, 就是說底層資料的改變會不會影響到它們。 @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; } //獲取顯示指定分組中的指定子選項的檢視 @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; } 複製程式碼
- 為 ExpandableListView 設定介面卡呀,一行程式碼搞定!
expandableListView.setAdapter(new MyExpandableListAdapter()); 複製程式碼
- 對於處理 Item 的點選事件,還是要設定監聽器,常用的有這幾類:
- setOnChildClickListener
- setOnGroupClickListener
- setOnGroupCollapseListener
- setOnGroupExpandListener 通過方法名我們就能知道各自的用途,它們分別設定單擊子選項、單擊分組項、分組合並、分組展開的監聽器。
//設定分組項的點選監聽事件 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(); // 請務必返回 false,否則分組不會展開 return false; } //設定子選項點選監聽事件 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; } }); 複製程式碼
到現在基本上完成了,我們來看一下執行效果~~

中,我會分享有關 ExpandableListView 的 Indicator(指示器)的使用,歡迎各位圍觀~