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( 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" > |
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" }, new int []{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 |
} |