前言
此篇文章只是本人學習 ExpandableListView 控件使用的筆記,如有雷同,純屬緣分!
首先我們來了解什么是 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的不同之處就是它可以展示兩級列表,分組可以單獨展開顯示子選項。這些選項的數(shù)據(jù)是通過ExpandableListAdapter關聯(lián)的)
本人理解:一個可以展示兩級列表的試圖,并且可以收縮子選項的控件,類似與 QQ 好友列表那種!
還是一言不合就上圖

上面的效果是不是和一般的 ExpandableListView 不一樣呀!這次的 ExpandableListView 控件的子項是橫向的?,F(xiàn)在我們就來實現(xiàn)上面的效果!
如果想實現(xiàn)原始的 ExpandableListView 請看下面的文章
Android ExpandableListView使用小結(一)
http://www.open-open.com/lib/view/open1406014566679.html
Now,我們來實現(xiàn)上面的效果:
第一步 創(chuàng)建 activity_main 布局文件 里面包含 ExpandableListView:
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<ExpandableListView
android:id="@+id/expandableListView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:groupIndicator="@null"/>
</RelativeLayout>
上面的布局就是一個簡單 ExpandableListView 并沒有什么多余的屬性,如果想了解更多屬性請點擊 傳送門 傳送到官網(wǎng)!
第二步 定義定義 MainActivity
MainActivity.java
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ExpandableListView expandableListView = (ExpandableListView) findViewById(R.id.expandableListView);
//自定義適配器
MeExpandableListAdapter mExpandableListAdapter = new MeExpandableListAdapter(MainActivity.this) ;
expandableListView.setAdapter(mExpandableListAdapter);
//默認展開的是那個
groupexpandableListView.expandGroup(0);
}
}
MainActivity 中的代碼很簡單,主要的代碼還是在自定義適配器 MeExpandableListAdapter 那里,現(xiàn)在我們來實現(xiàn)它。
第三步 實現(xiàn)自定義 MeExpandableListAdapter
(1) ExpandableListView 控件是由有分組視圖(group)和子選項視圖(child)組成的,所以現(xiàn)在先來定義它的分組視圖(group)和子選項視圖(child):
a.定義分組視圖(group)
expandablelistview_group.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<ImageView
android:id="@+id/group_icon"
android:layout_width="30dp"
android:layout_height="30dp"
android:layout_alignParentStart="true"
android:layout_centerVertical="true"
android:layout_margin="10dp"/>
<TextView
android:id="@+id/group_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_gravity="center"
android:layout_marginStart="10dp"
android:layout_toEndOf="@id/group_icon"
android:text=""
android:textColor="#000000"
android:textSize="20sp"/>
<ImageView
android:id="@+id/group_indicator"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentEnd="true"
android:layout_centerVertical="true"
android:layout_marginEnd="5dp"/>
</RelativeLayout>
上面就是分組視圖(group)的布局文件就是一個圖標+標題+收縮圖標,你也可以自己定義這個布局;
b.定義子選項視圖(child)
expandablelistview_child.xml
<?xml version="1.0" encoding="utf-8"?>
<GridView
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/child_gridView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#eeeeee"
android:numColumns="4"/>
在子選項視圖(child)中我選擇以一個 GridView 控件 這樣我就能橫向的顯示子選項視圖(child);
c.定義子選項視圖(child)中 GridView 中的item布局
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_centerInParent="true">
<ImageView
android:id="@+id/child_gridview_icon"
android:layout_width="30dp"
android:layout_height="30dp"
android:layout_centerHorizontal="true"
android:contentDescription="@string/app_name"/>
<TextView
android:id="@+id/child_gridview_item"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@id/child_gridview_icon"
android:layout_centerHorizontal="true"
android:layout_marginTop="3dp"
android:text=""
android:textColor="#000000"
android:textSize="15sp"/>
</RelativeLayout>
到現(xiàn)在我們把自定義適配器相關的布局都寫好了,我們就來實現(xiàn) MeExpandableListAdapter
(2)自定義 ExpandableListView的適配器 MeExpandableListAdapter (代碼略長)
MeExpandableListAdapter.java
public class MeExpandableListAdapter extends BaseExpandableListAdapter {
//分組視圖(group)的標題
private String[] group = {"group1", "group2"};
//分組視圖(group)的圖標
private int[] groupicon = {R.mipmap.group_icon_1, R.mipmap.group_icon_2};
//子選項視圖(child) 的標題
private String[][] gridViewChild = {{"child11", "child12"}, {"child21", "child22"}};
//子選項視圖(child) 的圖標
private int[][] gridImgChild = new int[][]{
{R.mipmap.ic_launcher, R.mipmap.ic_launcher},
{R.mipmap.ic_launcher, R.mipmap.ic_launcher}
};
private String[][] child = {{""}, {""}};
private LayoutInflater mInflater;
private Context context;
public MeExpandableListAdapter(Context context) {
mInflater = LayoutInflater.from(context);
this.context = context;
}
//expandablelistview的分組數(shù)
@Override
public int getGroupCount() {
return group.length;
}
//取得指定分組的子元素數(shù)
@Override
public int getChildrenCount(int groupPosition) {
return child[groupPosition].length;
}
//取得與給定分組關聯(lián)的數(shù)據(jù)
@Override
public Object getGroup(int groupPosition) {
return group[groupPosition];
}
//取得與給定子分組關聯(lián)的數(shù)據(jù)
@Override
public Object getChild(int groupPosition, int childPosition) {
return child[groupPosition][childPosition];
}
//取得指定分組的ID.該組ID必須在組中是唯一的.必須不同于其他所有ID(分組及子項目的ID)
@Override
public long getGroupId(int groupPosition) {
return groupPosition;
}
//取得給定分組中給定子視圖的ID. 該組ID必須在組中是唯一的.必須不同于其他所有ID(分組及子項目的ID)
@Override
public long getChildId(int groupPosition, int childPosition) {
return childPosition;
}
@Override
public boolean hasStableIds() {
return true;
}
//重寫GroupView的布局
@Override
public View getGroupView(int groupPosition, boolean isExpanded, View convertView, ViewGroup parent) {
if (convertView == null) {
mViewChild = new ViewChild();
convertView = mInflater.inflate(R.layout.expandablelistview_group, parent, false);
mViewChild.textView = (TextView) convertView.findViewById(R.id.group_name);
mViewChild.imageView = (ImageView) convertView.findViewById(R.id.group_indicator);
mViewChild.imageHead = (ImageView) convertView.findViewById(R.id.group_icon);
convertView.setTag(mViewChild);
} else {
mViewChild = (ViewChild) convertView.getTag();
}
if (isExpanded)
mViewChild.imageView.setImageResource(R.mipmap.group_indicator_2);
else
mViewChild.imageView.setImageResource(R.mipmap.group_indicator_1);
mViewChild.textView.setText(getGroup(groupPosition).toString());
mViewChild.imageHead.setImageResource(groupicon[groupPosition]);
return convertView;
}
//重寫ChildView的布局
@Override
public View getChildView(int groupPosition, int childPosition, boolean isLastChild, View convertView, ViewGroup parent) {
if (convertView == null) {
mViewChild = new ViewChild();
convertView = mInflater.inflate(R.layout.expandablelistview_chilld, parent, false);
mViewChild.gridView = (GridView) convertView.findViewById(R.id.child_gridView);
convertView.setTag(mViewChild);
} else {
mViewChild = (ViewChild) convertView.getTag();
}
SimpleAdapter mSimpleAdapter = new SimpleAdapter(context,
setGridViewData(gridViewChild[groupPosition],
gridImgChild[groupPosition]),
R.layout.chilld_gridview_item, new String[]{
"child_gridview_item", "child_gridview_img1"},
new int[]{R.id.child_gridview_item,
R.id.child_gridview_icon});
mViewChild.gridView.setAdapter(mSimpleAdapter);
setGridViewListener(mViewChild.gridView, groupPosition);
return convertView;
}
//設置GridView點擊事件監(jiān)聽
private void setGridViewListener(final GridView gridView, final int groupPosition) {
gridView.setOnItemClickListener(new GridView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
RelativeLayout ff = (RelativeLayout) view;
TextView gg = (TextView) ff
.findViewById(R.id.child_gridview_item);
Toast.makeText(context, "你點擊了" + gg.getText().toString(), Toast.LENGTH_SHORT).show();
}
});
}
//設置GridView數(shù)據(jù)
private ArrayList<HashMap<String, Object>> setGridViewData(String[] data, int[] img) {
ArrayList<HashMap<String, Object>> gridItem = new ArrayList<>(); for (int i = 0; i < data.length; i++) {
HashMap<String, Object> hashMap = new HashMap<>();
hashMap.put("child_gridview_item", data[i]);
hashMap.put("child_gridview_img1", img[i]);
gridItem.add(hashMap);
}
return gridItem;
}
@Override
public boolean isChildSelectable(int groupPosition, int childPosition) {
return true;
}
ViewChild mViewChild;
static class ViewChild {
ImageView imageHead;
ImageView imageView;
TextView textView;
GridView gridView;
}
}
上面的代碼都有注釋,相信大家都看得懂。到此,我們就實現(xiàn)了 ExpandableListView 控件的子項是橫向的效果。
總結
其實這次 ExpandableListVie 效果實現(xiàn)主要的就是自定義 BaseExpandableListAdapter 中 getChildView() 的方法,只要把 子選項視圖換為一個 GridView 布局就行了(我想:如果子選項視圖換成其他控件也行,下次試試)。