原文
ExpandableListView是android中可以实现下拉list的一个控件,是一个垂直滚动的心事两个级别列表项手风琴试图,列表项是来自ExpandableListViewaAdapter,组可以单独展开。
重要方法:
01 | expandGroup ( int groupPos) ; |
02 | setSelectedGroup ( int groupPosition) ; |
04 | setSelectedChild ( int groupPosition, int childPosition, boolean shouldExpandGroup); |
06 | getPackedPositionGroup ( long packedPosition); |
08 | getPackedPositionForChild ( int groupPosition, int childPosition) ; |
10 | getPackedPositionType ( long packedPosition); |
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" > |
07 | android:id = "@+id/expandableListView" |
08 | android:layout_width = "fill_parent" |
09 | android:layout_height = "wrap_content" |
003 | import java.util.ArrayList; |
004 | import java.util.List; |
006 | import javax.security.auth.PrivateCredentialPermission; |
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; |
019 | public class ExpandableListViewDemo extends Activity { |
020 | /** Called when the activity is first created. */ |
024 | private List<String> groupArray; |
025 | private List<List<String>> childArray; |
026 | private ExpandableListView expandableListView_one; |
029 | public void onCreate(Bundle savedInstanceState) { |
030 | super .onCreate(savedInstanceState); |
032 | setContentView(R.layout.expandablelistview); |
033 | expandableListView_one =(ExpandableListView)findViewById(R.id.expandableListView); |
034 | groupArray = new ArrayList<String>(); |
035 | childArray = new ArrayList<List<String>>(); |
090 | public Object getGroup( int groupPosition) { |
092 | return getGroup(groupPosition); |
096 | public int getGroupCount() { |
098 | return groupArray.size(); |
102 | public long getGroupId( int groupPosition) { |
104 | return groupPosition; |
108 | public View getGroupView( int groupPosition, boolean isExpanded, |
109 | View convertView, ViewGroup parent) { |
111 | String string=groupArray.get(groupPosition); |
112 | return getGenericView(string); |
116 | public boolean hasStableIds() { |
122 | public boolean isChildSelectable( int groupPosition, int childPosition) |
128 | private TextView getGenericView(String string ) |
130 | AbsListView.LayoutParams layoutParams = new AbsListView.LayoutParams( |
131 | ViewGroup.LayoutParams.MATCH_PARENT, |
132 | ViewGroup.LayoutParams.WRAP_CONTENT); |
134 | TextView textView = new TextView(activity); |
135 | textView.setLayoutParams(layoutParams); |
137 | textView.setGravity(Gravity.CENTER_VERTICAL |Gravity.LEFT); |
139 | textView.setPadding( 40 , 0 , 0 , 0 ); |
140 | textView.setText(string); |
145 | private void initdate() |
147 | addInfo( "语言" , new String[]{ "Oracle" , "Java" , "Linux" , "Jquery" }); |
148 | addInfo( "男人的需求" , new String[]{ "金钱" , "事业" , "权力" , "女人" , "房子" , "车" , "球" }); |
150 | private void addInfo(String group,String []child) { |
152 | groupArray.add(group); |
154 | List<String> childItem = new ArrayList<String>(); |
156 | for ( int index= 0 ;index<child.length;index++) |
158 | childItem.add(child[index]); |
160 | childArray.add(childItem); |
运行效果:

注释修改如下代码:
06 | groupArray.add( "移动开发" ); |
07 | List<String> arrayList = new ArrayList<String>(); |
08 | arrayList.add( "Android" ); |
10 | arrayList.add( "Windows Phone" ); |
12 | for ( int index= 0 ;index<groupArray.size();++index) |
14 | childArray.add(arrayList); |
16 | expandableListView_one.setAdapter( new ExpandableListViewaAdapter(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" > |
07 | android:id = "@+id/expandableListView" |
08 | android:layout_width = "fill_parent" |
09 | android:layout_height = "wrap_content" |
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" > |
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" |
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" > |
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" /> |
定义java文件:ExpandableListViewDemo_two.java
003 | import java.util.ArrayList; |
004 | import java.util.HashMap; |
005 | import java.util.List; |
006 | import java.util.Map; |
008 | import javax.security.auth.PrivateCredentialPermission; |
011 | import com.test.ExpandableListViewDemo.ExpandableListViewaAdapter; |
012 | import com.test.R.id; |
013 | import com.test.R.layout; |
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; |
027 | public class ExpandableListViewDemo_two extends Activity { |
028 | /** Called when the activity is first created. */ |
029 | private ExpandableListView expandableListView_one; |
031 | public void onCreate(Bundle savedInstanceState) |
033 | super .onCreate(savedInstanceState); |
034 | setContentView(R.layout.expandablelistview); |
035 | expandableListView_one =(ExpandableListView)findViewById(R.id.expandableListView); |
037 | Map<String, String> title_1 = new HashMap<String, String>(); |
038 | Map<String, String> title_2 = new HashMap<String, String>(); |
040 | title_1.put( "group" , "移动开发" ); |
041 | title_2.put( "group" , "男人的需求" ); |
044 | List<Map<String, String>> gruops = new ArrayList<Map<String,String>>(); |
052 | Map<String, String> content_1 = new HashMap<String, String>(); |
053 | Map<String, String> content_2 = new HashMap<String, String>(); |
055 | content_1.put( "child" , "ANDROID" ); |
056 | content_2.put( "child" , "IOS" ); |
058 | List<Map<String, String>> childs_1 = new ArrayList<Map<String,String>>(); |
059 | childs_1.add(content_1); |
060 | childs_1.add(content_2); |
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>(); |
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); |
076 | List<List<Map<String, String>>> childs = new ArrayList<List<Map<String,String>>>(); |
077 | childs.add(childs_1); |
078 | childs.add(childs_2); |
082 | * 使用SimpleExpandableListAdapter显示ExpandableListView |
085 | * 参数 3 .一级条目对应的布局文件 (expandablelistview_groups.xml文件 |
086 | * 参数 4 .fromto,就是map中的key,指定要显示的对象 |
087 | * 参数 5 .与参数 4 对应,指定要显示在groups中的id |
090 | * 参数 9 .与参数 8 对应,指定要显示在childs中的id |
091 | / SimpleExpandableListAdapter adapter = new SimpleExpandableListAdapter( |
092 | this , gruops, R.drawable.expandablelistview_groups, new String[]{ "group" }, new int []{R.id.textGroup}, |
093 | childs, R.drawable.expandablelistview_child, new String[]{ "child" }, new int []{R.id.textChild} |
097 | expandableListView_one.setAdapter(adapter); |
098 | expandableListView_one.setOnChildClickListener(listener); |
100 | private OnChildClickListener listener = new OnChildClickListener() { |
102 | public boolean onChildClick(ExpandableListView parent, View v, |
103 | int groupPosition, int childPosition, long id) { |
109 | private void toast(String str) { |
110 | Toast.makeText( this , str, Toast.LENGTH_LONG).show(); |
上面的样式也可以使用系统的自带的样式如下:
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) { |
04 | for ( int i = 0 ; i < len; i++) { |
05 | TextView v = (TextView)view.findViewById(to[i]); |
07 | v.setText((String)data.get(from[i])); |
从上面的方法中可以看出 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) { |
04 | boolean isBound = false ; |
05 | for ( int i = 0 ; i < len; i++) { |
06 | final View v = view.findViewById(to[i]); |
08 | final Object _data = data.get(from[i]); |
09 | String text = _data == null ? "" : data.toString(); |
13 | if (mViewBinder != null ) { |
14 | isBound = mViewBinder.setViewValue(v, data.get(from[i]), text); |
17 | TextView _v = (TextView)v; |
18 | _v.setText((String)data.get(from[i])); |