Android中ListView的用法基本上學的時候都會使用,其中可以使用ArrayAdapter,SimpleAdapter,BaseAdapter去實現,這次主要使用的ExpandableListView展示一種兩層的效果,ExpandableListView是android中可以實現下拉list的一個控件類似於QQ那種我好友之后就是一排自己的好友,就是兩層效果,實現的話使用SimpleExpandableListAdapter即可。
布局文件
先看下效果:

main中xml代碼:
<Button
android:onClick="test"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="FlyElephant" />
<ExpandableListView
android:id="@id/android:list"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:drawSelectorOnTop="false" />
定義一個省份的province.xml:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<TextView
android:id="@+id/list_provinceText"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:paddingBottom="8px"
android:paddingLeft="30px"
android:paddingRight="5px"
android:paddingTop="8px"
android:textSize="20sp" />
</LinearLayout>
定義了一個地區的child.xml:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<TextView
android:id="@+id/child_text"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:paddingBottom="8px"
android:paddingLeft="30px"
android:paddingRight="5px"
android:paddingTop="8px"
android:textSize="20sp" />
</LinearLayout>
Demo實現
主要實現代碼,代碼中都已經注釋,其中最主要的SimpleExpandableListAdapter中的參數,這個參數太多,很容易弄錯,可以看下注釋或者API文檔:
// 創建一級條目
List<Map<String, String>> provinces = new ArrayList<Map<String, String>>();
//創建兩個省份一級條目
Map<String, String> firstProvince= new HashMap<String, String>();
firstProvince.put("province", "河南");
Map<String, String> secondProvince= new HashMap<String, String>();
secondProvince.put("province", "北京");
provinces.add(firstProvince);
provinces.add(secondProvince);
// 創建一級條目下的的二級地區條目
List<Map<String, String>> childList1= new ArrayList<Map<String, String>>();
//同樣是在一級條目目錄下創建兩個對應的二級條目目錄
Map<String, String> child1= new HashMap<String, String>();
child1.put("child", "鄭州");
Map<String, String> child2 = new HashMap<String, String>();
child2.put("child", "開封");
childList1.add(child1);
childList1.add(child2);
//同上
List<Map<String, String>> childList2 = new ArrayList<Map<String, String>>();
Map<String, String> child3 = new HashMap<String, String>();
child3.put("child", "海淀");
Map<String, String> child4 = new HashMap<String, String>();
child4.put("child", "昌平");
childList2.add(child3);
childList2.add(child4);
// 將二級條目放在一個集合里,供顯示時使用
List<List<Map<String, String>>> childs = new ArrayList<List<Map<String, String>>>();
childs.add(childList1);
childs.add(childList2);
/**
* 使用SimpleExpandableListAdapter顯示ExpandableListView
* 參數1.上下文對象Context
* 參數2.一級條目目錄集合
* 參數3.一級條目對應的布局文件
* 參數4.fromto,就是map中的key,指定要顯示的對象
* 參數5.與參數4對應,指定要顯示在groups中的id
* 參數6.二級條目目錄集合
* 參數7.二級條目對應的布局文件
* 參數8.fromto,就是map中的key,指定要顯示的對象
* 參數9.與參數8對應,指定要顯示在childs中的id
*/
SimpleExpandableListAdapter adapter = new SimpleExpandableListAdapter(
this, provinces, R.layout.list_group, new String[] { "province" },
new int[] { R.id.list_groupText }, childs, R.layout.child,
new String[] { "child" }, new int[] { R.id.child_text });
setListAdapter(adapter);
這個mainActivity需要繼承ExpandableListActivity,當然你可以設置其中的點擊事件,只要重寫一下方法即可:
/**
* 設置哪個二級目錄被默認選中
*/
@Override
public boolean setSelectedChild(int groupPosition, int childPosition,
boolean shouldExpandGroup) {
//do something
return super.setSelectedChild(groupPosition, childPosition,
shouldExpandGroup);
}
/**
* 設置哪個一級目錄被默認選中
*/
@Override
public void setSelectedGroup(int groupPosition) {
//do something
super.setSelectedGroup(groupPosition);
}
/**
* 當二級條目被點擊時響應
*/
@Override
public boolean onChildClick(ExpandableListView parent, View v,
int groupPosition, int childPosition, long id) {
//do something
return super.onChildClick(parent, v, groupPosition, childPosition, id);
}
效果如下:

上面這個例子寫的有點單調,其實第二個你子的布局直接是空的也行,例如定義一個images.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal" >
<ImageView
android:src="@drawable/open"
android:layout_width="20dp"
android:layout_height="20dp" />
<TextView
android:id="@+id/txtName"
android:paddingLeft="10dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</LinearLayout>
然后定義一個items.xml
<?xml version="1.0" encoding="utf-8"?>
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/items"
android:layout_width="wrap_content"
android:layout_height="wrap_content" >
</TextView>
代碼調用:
public class MyExpandleActivity extends Activity {
/**
* 實現可擴展展開列ExpandableListView的三種方式
* 一是使用SimpleExpandableListAdpater將兩個List集合包裝成ExpandableListView 二是
* 擴展BaseExpandableListAdpter
* 三是使用simpleCursorTreeAdapter將Cursor中的數據包裝成SimpleCuroTreeAdapter
*/
private String[] names = { "騰訊", "百度", "阿里巴巴" };
private String[][] childnames = { { "馬化騰", "張小龍","社交"},
{ "李彥宏", "馬東敏","搜索" }, { "馬雲", "陸兆禧","電商" } };
private ExpandableListView ep;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_my_expandle);
// 定義父列表項List數據集合
List<Map<String, String>> group = new ArrayList<Map<String, String>>();
// 定義子列表項List數據集合
List<List<Map<String, String>>> ss = new ArrayList<List<Map<String, String>>>();
for (int i = 0; i < names.length; i++) {
// 提供父列表的數據
Map<String, String> maps = new HashMap<String, String>();
maps.put("names", names[i]);
group.add(maps);
// 提供當前父列的子列數據
List<Map<String, String>> child = new ArrayList<Map<String, String>>();
for (int j = 0; j < names.length; j++) {
Map<String, String> mapsj = new HashMap<String, String>();
mapsj.put("map", childnames[i][j]);
child.add(mapsj);
}
ss.add(child);
}
/**
* 第一個參數 應用程序接口 this 第二個父列List<?extends Map<String,Object>>集合 為父列提供數據
* 第三個參數 父列顯示的組件資源文件 第四個參數 鍵值列表 父列Map字典的key 第五個要顯示的父列組件id 第六個 子列的顯示資源文件
* 第七個參數 鍵值列表的子列Map字典的key 第八個要顯示子列的組件id
*/
SimpleExpandableListAdapter expand = new SimpleExpandableListAdapter(
this, group, R.layout.images, new String[] { "names" },
new int[] { R.id.txtName }, ss, R.layout.items,
new String[] { "map" }, new int[] { R.id.items });
ep = (ExpandableListView) findViewById(R.id.expanable_mylist);
ep.setAdapter(expand);
}
}
效果跟上面相同:

