android ExpandableListView详解
ExpandableListView是android中可以实现下拉list的一个控件,是一个垂直滚动的心事两个级别列表项手风琴试图,列表项是来自ExpandableListViewaAdapter,组可以单独展开。
重要方法:
01 |
expandGroup (int groupPos) ;//在分组列表视图中 展开一组, |
02 |
setSelectedGroup (int groupPosition) ;//设置选择指定的组。 |
03 |
04 |
setSelectedChild (int groupPosition, int childPosition, boolean shouldExpandGroup);//设置选择指定的子项。 |
05 |
06 |
getPackedPositionGroup (long packedPosition);//返回所选择的组 |
07 |
08 |
getPackedPositionForChild (int groupPosition, int childPosition) ;//返回所选择的子项 |
09 |
10 |
getPackedPositionType (long packedPosition);//返回所选择项的类型(Child,Group) |
11 |
12 |
isGroupExpanded (int groupPosition);//判断此组是否展开 |
expandableListView.setDivider();这个是设定每个Group之间的分割线。
expandableListView.setGroupIndicator();这个是设定每个Group之前的那个图标。
expandableListView.collapseGroup(int group); 将第group组收起
ExpandableListAdapter
一个接口,将基础数据链接到一个ExpandableListView。 此接口的实施将提供访问Child的数据(由组分类),并实例化的Child和Group。
1.重要方法
getChildId (int groupPosition, int childPosition) 获取与在给定组给予孩子相关的数据。
getChildrenCount (int groupPosition) 返回在指定Group的Child数目。
案例:
首先定义个一个布局文件expandablelistview.xml
01 |
<?xml version="1.0" encoding="utf-8"?> |
02 |
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" |
03 |
android:layout_width="fill_parent" |
04 |
android:layout_height="fill_parent" |
05 |
android:orientation="vertical" > |
06 |
<ExpandableListView |
07 |
android:id ="@+id/expandableListView" |
08 |
android:layout_width ="fill_parent" |
09 |
android:layout_height ="wrap_content" |
10 |
> |
11 |
</ExpandableListView> |
12 |
</LinearLayout> |
001 |
package com.test; |
002 |
003 |
import java.util.ArrayList; |
004 |
import java.util.List; |
005 |
006 |
import javax.security.auth.PrivateCredentialPermission; |
007 |
008 |
import android.app.Activity; |
009 |
import android.os.Bundle; |
010 |
import android.view.Gravity; |
011 |
import android.view.View; |
012 |
import android.view.ViewGroup; |
013 |
import android.view.Window; |
014 |
import android.widget.AbsListView; |
015 |
import android.widget.BaseExpandableListAdapter; |
016 |
import android.widget.ExpandableListView; |
017 |
import android.widget.TextView; |
018 |
019 |
public class ExpandableListViewDemo extends Activity { |
020 |
/** Called when the activity is first created. */ |
021 |
|
022 |
//定义两个List用来控制Group和Child中的String; |
023 |
|
024 |
private List<String> groupArray;//组列表 |
025 |
private List<List<String>> childArray;//子列表 |
026 |
private ExpandableListView expandableListView_one; |
027 |
|
028 |
@Override |
029 |
public void onCreate(Bundle savedInstanceState) { |
030 |
super.onCreate(savedInstanceState); |
031 |
// requestWindowFeature(Window.FEATURE_NO_TITLE); //设置为无标题 |
032 |
setContentView(R.layout.expandablelistview); |
033 |
expandableListView_one =(ExpandableListView)findViewById(R.id.expandableListView); |
034 |
groupArray =new ArrayList<String>(); |
035 |
childArray = new ArrayList<List<String>>(); |
036 |
|
037 |
/*-第一季-*/ |
038 |
initdate(); |
039 |
expandableListView_one.setAdapter(new ExpandableListViewaAdapter(ExpandableListViewDemo.this)); |
040 |
|
041 |
/*-第二季-*/ |
042 |
// groupArray.add("移动开发"); |
043 |
// List<String> arrayList = new ArrayList<String>(); |
044 |
// arrayList.add("Android"); |
045 |
// arrayList.add("IOS"); |
046 |
// arrayList.add("Windows Phone"); |
047 |
// //组循环 |
048 |
// for(int index=0;index<groupArray.size();++index) |
049 |
// { |
050 |
// childArray.add(arrayList); |
051 |
// } |
052 |
// expandableListView_one.setAdapter(new ExpandableListViewaAdapter(ExpandableListViewDemo.this)); |
053 |
|
054 |
} |
055 |
class ExpandableListViewaAdapter extends BaseExpandableListAdapter { |
056 |
Activity activity; |
057 |
public ExpandableListViewaAdapter(Activity a) |
058 |
{ |
059 |
activity = a; |
060 |
} |
061 |
/*-----------------Child */ |
062 |
@Override |
063 |
public Object getChild(int groupPosition, int childPosition) { |
064 |
// TODO Auto-generated method stub |
065 |
return childArray.get(groupPosition).get(childPosition); |
066 |
} |
067 |
068 |
@Override |
069 |
public long getChildId(int groupPosition, int childPosition) { |
070 |
// TODO Auto-generated method stub |
071 |
return childPosition; |
072 |
} |
073 |
074 |
@Override |
075 |
public View getChildView(int groupPosition, int childPosition, |
076 |
boolean isLastChild, View convertView, ViewGroup parent) { |
077 |
|
078 |
String string =childArray.get(groupPosition).get(childPosition); |
079 |
|
080 |
return getGenericView(string); |
081 |
} |
082 |
083 |
@Override |
084 |
public int getChildrenCount(int groupPosition) { |
085 |
// TODO Auto-generated method stub |
086 |
return childArray.get(groupPosition).size(); |
087 |
} |
088 |
/* ----------------------------Group */ |
089 |
@Override |
090 |
public Object getGroup(int groupPosition) { |
091 |
// TODO Auto-generated method stub |
092 |
return getGroup(groupPosition); |
093 |
} |
094 |
095 |
@Override |
096 |
public int getGroupCount() { |
097 |
// TODO Auto-generated method stub |
098 |
return groupArray.size(); |
099 |
} |
100 |
101 |
@Override |
102 |
public long getGroupId(int groupPosition) { |
103 |
// TODO Auto-generated method stub |
104 |
return groupPosition; |
105 |
} |
106 |
107 |
@Override |
108 |
public View getGroupView(int groupPosition, boolean isExpanded, |
109 |
View convertView, ViewGroup parent) { |
110 |
|
111 |
String string=groupArray.get(groupPosition); |
112 |
return getGenericView(string); |
113 |
} |
114 |
115 |
@Override |
116 |
public boolean hasStableIds() { |
117 |
// TODO Auto-generated method stub |
118 |
return false; |
119 |
} |
120 |
121 |
@Override |
122 |
public boolean isChildSelectable(int groupPosition, int childPosition) |
123 |
{ |
124 |
// TODO Auto-generated method stub |
125 |
return true; |
126 |
} |
127 |
|
128 |
private TextView getGenericView(String string ) |
129 |
{ |
130 |
AbsListView.LayoutParams layoutParams =new AbsListView.LayoutParams( |
131 |
ViewGroup.LayoutParams.MATCH_PARENT, |
132 |
ViewGroup.LayoutParams.WRAP_CONTENT); |
133 |
|
134 |
TextView textView =new TextView(activity); |
135 |
textView.setLayoutParams(layoutParams); |
136 |
|
137 |
textView.setGravity(Gravity.CENTER_VERTICAL |Gravity.LEFT); |
138 |
|
139 |
textView.setPadding(40, 0, 0, 0); |
140 |
textView.setText(string); |
141 |
return textView; |
142 |
} |
143 |
} |
144 |
|
145 |
private void initdate() |
146 |
{ |
147 |
addInfo("语言", new String[]{"Oracle","Java","Linux","Jquery"}); |
148 |
addInfo("男人的需求", new String[]{"金钱","事业","权力","女人","房子","车","球"}); |
149 |
} |
150 |
private void addInfo(String group,String []child) { |
151 |
|
152 |
groupArray.add(group); |
153 |
|
154 |
List<String> childItem =new ArrayList<String>(); |
155 |
|
156 |
for(int index=0;index<child.length;index++) |
157 |
{ |
158 |
childItem.add(child[index]); |
159 |
} |
160 |
childArray.add(childItem); |
161 |
} |
162 |
} |
运行效果:

注释修改如下代码:
01 |
/*-第一季-*/ |
02 |
// initdate(); |
03 |
// expandableListView_one.setAdapter(new ExpandableListViewaAdapter(ExpandableListViewDemo.this)); |
04 |
|
05 |
/*-第二季-*/ |
06 |
groupArray.add("移动开发"); |
07 |
List<String> arrayList = new ArrayList<String>(); |
08 |
arrayList.add("Android"); |
09 |
arrayList.add("IOS"); |
10 |
arrayList.add("Windows Phone"); |
11 |
//组循环 |
12 |
for(int index=0;index<groupArray.size();++index) |
13 |
{ |
14 |
childArray.add(arrayList); |
15 |
} |
16 |
expandableListView_one.setAdapter(newExpandableListViewaAdapter(ExpandableListViewDemo.this)); |
运行效果:

★★★★★★★★★★★★★★★★★★★★
案例二:
1.定义一个主界面expandablelistview.xml
01 |
<?xml version="1.0" encoding="utf-8"?> |
02 |
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" |
03 |
android:layout_width="fill_parent" |
04 |
android:layout_height="fill_parent" |
05 |
android:orientation="vertical" > |
06 |
<ExpandableListView |
07 |
android:id ="@+id/expandableListView" |
08 |
android:layout_width ="fill_parent" |
09 |
android:layout_height ="wrap_content" |
10 |
> |
11 |
</ExpandableListView> |
12 |
</LinearLayout> |
2.在res/drawable目录下创建样式文件expandablelistview_groups.xml该界面是组界面:
01 |
<?xml version="1.0" encoding="utf-8"?> |
02 |
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" |
03 |
android:layout_width="fill_parent" |
04 |
android:layout_height="fill_parent" |
05 |
android:orientation="vertical" > |
06 |
<TextView |
07 |
android:id="@+id/textGroup" |
08 |
android:layout_width="fill_parent" |
09 |
android:layout_height="fill_parent" |
10 |
android:paddingLeft="40px" |
11 |
android:paddingTop="6px" |
12 |
android:paddingBottom="6px" |
13 |
android:textSize="15sp" |
14 |
android:text="No data" |
15 |
> |
16 |
</TextView> |
17 |
</LinearLayout> |
3.在res/drawable目录下创建样式文件expandablelistview_child.xml;是子控件,直接显示列表内容
01 |
<?xml version="1.0" encoding="utf-8"?> |
02 |
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" |
03 |
android:layout_width="fill_parent" |
04 |
android:layout_height="fill_parent" |
05 |
android:orientation="vertical" > |
06 |
<TextView |
07 |
android:id="@+id/textChild" |
08 |
android:layout_width="fill_parent" |
09 |
android:layout_height="fill_parent" |
10 |
android:paddingLeft="60px" |
11 |
android:paddingTop="10px" |
12 |
android:paddingBottom="10px" |
13 |
android:textSize="20sp" |
14 |
android:text="No Data" /> |
15 |
</LinearLayout> |
定义java文件:ExpandableListViewDemo_two.java
001 |
package com.test; |
002 |
003 |
import java.util.ArrayList; |
004 |
import java.util.HashMap; |
005 |
import java.util.List; |
006 |
import java.util.Map; |
007 |
008 |
import javax.security.auth.PrivateCredentialPermission; |
009 |
010 |
import com.test.R; |
011 |
import com.test.ExpandableListViewDemo.ExpandableListViewaAdapter; |
012 |
import com.test.R.id; |
013 |
import com.test.R.layout; |
014 |
015 |
import android.app.Activity; |
016 |
import android.os.Bundle; |
017 |
import android.view.Gravity; |
018 |
import android.view.View; |
019 |
import android.view.ViewGroup; |
020 |
import android.view.Window; |
021 |
import android.widget.AbsListView; |
022 |
import android.widget.BaseExpandableListAdapter; |
023 |
import android.widget.ExpandableListView; |
024 |
import android.widget.SimpleExpandableListAdapter; |
025 |
import android.widget.TextView; |
026 |
027 |
public class ExpandableListViewDemo_two extends Activity { |
028 |
/** Called when the activity is first created. */ |
029 |
private ExpandableListView expandableListView_one; |
030 |
@Override |
031 |
public void onCreate(Bundle savedInstanceState) |
032 |
{ |
033 |
super.onCreate(savedInstanceState); |
034 |
setContentView(R.layout.expandablelistview); |
035 |
expandableListView_one =(ExpandableListView)findViewById(R.id.expandableListView); |
036 |
//创建二个一级条目标题 |
037 |
Map<String, String> title_1 = new HashMap<String, String>(); |
038 |
Map<String, String> title_2 = new HashMap<String, String>(); |
039 |
|
040 |
title_1.put("group", "移动开发"); |
041 |
title_2.put("group", "男人的需求"); |
042 |
|
043 |
//创建一级条目容器 |
044 |
List<Map<String, String>> gruops = new ArrayList<Map<String,String>>(); |
045 |
|
046 |
gruops.add(title_1); |
047 |
gruops.add(title_2); |
048 |
|
049 |
//创建二级条目内容 |
050 |
|
051 |
//内容一 |
052 |
Map<String, String> content_1 = new HashMap<String, String>(); |
053 |
Map<String, String> content_2 = new HashMap<String, String>(); |
054 |
|
055 |
content_1.put("child", "ANDROID"); |
056 |
content_2.put("child", "IOS"); |
057 |
|
058 |
List<Map<String, String>> childs_1 = new ArrayList<Map<String,String>>(); |
059 |
childs_1.add(content_1); |
060 |
childs_1.add(content_2); |
061 |
|
062 |
//内容二 |
063 |
Map<String, String> content_3 = new HashMap<String, String>(); |
064 |
Map<String, String> content_4 = new HashMap<String, String>(); |
065 |
Map<String, String> content_5 = new HashMap<String, String>(); |
066 |
|
067 |
content_3.put("child", "金钱"); |
068 |
content_4.put("child", "权力"); |
069 |
content_5.put("child", "女人"); |
070 |
List<Map<String, String>> childs_2 = new ArrayList<Map<String,String>>(); |
071 |
childs_2.add(content_3); |
072 |
childs_2.add(content_4); |
073 |
childs_2.add(content_5); |
074 |
|
075 |
//存放两个内容, 以便显示在列表中 |
076 |
List<List<Map<String, String>>> childs = new ArrayList<List<Map<String,String>>>(); |
077 |
childs.add(childs_1); |
078 |
childs.add(childs_2); |
079 |
|
080 |
//创建ExpandableList的Adapter容器 |
081 |
/** |
082 |
* 使用SimpleExpandableListAdapter显示ExpandableListView |
083 |
* 参数1.上下文对象Context |
084 |
* 参数2.一级条目目录集合 |
085 |
* 参数3.一级条目对应的布局文件 (expandablelistview_groups.xml文件 |
086 |
* 参数4.fromto,就是map中的key,指定要显示的对象 |
087 |
* 参数5.与参数4对应,指定要显示在groups中的id |
088 |
* 参数6.二级条目目录集合 |
089 |
* 参数7.二级条目对应的布局文件 |
090 |
* 参数9.与参数8对应,指定要显示在childs中的id |
091 |
/ SimpleExpandableListAdapter adapter = new SimpleExpandableListAdapter( |
092 |
this, gruops, R.drawable.expandablelistview_groups, new String[]{"group"}, newint[]{R.id.textGroup}, |
093 |
childs, R.drawable.expandablelistview_child, new String[]{"child"}, new int[]{R.id.textChild} |
094 |
); |
095 |
|
096 |
//加入列表 |
097 |
expandableListView_one.setAdapter(adapter); |
098 |
expandableListView_one.setOnChildClickListener(listener); |
099 |
} |
100 |
private OnChildClickListener listener =new OnChildClickListener() { |
101 |
@Override |
102 |
public boolean onChildClick(ExpandableListView parent, View v, |
103 |
int groupPosition, int childPosition, long id) { |
104 |
// TODO Auto-generated method stub |
105 |
toast("点击了"); |
106 |
return false; |
107 |
} |
108 |
}; |
109 |
private void toast(String str) { |
110 |
Toast.makeText(this, str, Toast.LENGTH_LONG).show(); |
111 |
} |
112 |
} |
上面的样式也可以使用系统的自带的样式如下:
android.R.layout.simple_expandable_list_item_1,//层显示样式 ,系统自定义
android.R.layout.simple_expandable_list_item_2,
运行效果:

案例三:如果group中有个ImageVIew将会是什么情况呢?
在SimpleExpandableListAdapter中有如下方法:
01 |
private void bindView(View view, Map<String, ?> data, String[] from, int[] to) { |
02 |
int len = to.length; |
03 |
04 |
for (int i = 0; i < len; i++) { |
05 |
TextView v = (TextView)view.findViewById(to[i]); |
06 |
if (v != null) { |
07 |
v.setText((String)data.get(from[i])); |
08 |
} |
09 |
} |
10 |
} |
从上面的方法中可以看出 SimpleExpandableListAdapter把所以的View都当成TextView来处理了,而不像SimpleAdapter可以自动判断View的类型,自动绑定,解决版本就是重写bingview回调一下试试:
01 |
public class MyExpandableListAdapter extends BaseExpandableListAdapter{ |
02 |
private void bindView(View view, Map<String, ?> data, String[] from, int[] to) { |
03 |
int len = to.length; |
04 |
boolean isBound = false; |
05 |
for (int i = 0; i < len; i++) { |
06 |
final View v = view.findViewById(to[i]); |
07 |
if (v!=null) { |
08 |
final Object _data = data.get(from[i]); |
09 |
String text = _data == null ? "" : data.toString(); |
10 |
if (text == null) { |
11 |
text = ""; |
12 |
} |
13 |
if (mViewBinder != null) {//如果Binder不为空,使用Binder进行处理 |
14 |
isBound = mViewBinder.setViewValue(v, data.get(from[i]), text); |
15 |
} |
16 |
if (!isBound) {//如果Binder跳过,使用原来的方法进行处理 |
17 |
TextView _v = (TextView)v; |
18 |
_v.setText((String)data.get(from[i])); |
19 |
} |
20 |
} |
21 |
} |
22 |
} |
23 |
} |

浙公网安备 33010602011771号