android开发中也经常会用到双层数据列表(树形数据列表),ExpandableListView是满足这一要求的一个组建之一,下面对ExpandableListView使用做一些简单总结:
树形列表即第一层列表的数据 单元也是一个列表型的数据例如我们使用的QQ我们对我们的好友分类(分组),这时所有的分组形成了一个分组列表(如:好友,同学,同事,小蜜……,等等这就形成了一个一级列表),每个分组下又分别包含一些成员,分别包含的成员又各自形成了一个列表。这些列表统称为二级列表。如图
其二级列表有点类似与矩阵图只是他们列数是不固定的。好了废话少说了那么在android上如何使用ExpandableListView展示这样的一种类型的数据呢。下面通过一些示例来说明吧.
1, 建立工程,编写main.xml 文件
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<ExpandableListView
android:id="@+id/evl_list"
android:layout_width="match_parent"
android:layout_height="wrap_content" >
</ExpandableListView>
</LinearLayout>
group.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="wrap_content"
android:descendantFocusability="blocksDescendants"
android:orientation="vertical" >
<TextView
android:id="@+id/tv_group"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</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="wrap_content"
android:orientation="vertical" >
<TextView
android:id="@+id/tv_child"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</LinearLayout>
3,MainActivity.java
package com.cn.testexpansablelist;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import android.os.Bundle;
import android.app.Activity;
import android.view.Menu;
import android.widget.ExpandableListView;
public class MainActivity extends Activity {
private ExpandableListView elv_List;
private ArrayList<String> groups;
private ArrayList<ArrayList<String>> children;
LinkedHashMap<String, ArrayList<String>> values;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
elv_List = (ExpandableListView) this.findViewById(R.id.evl_list);
// elv_List.setAdapter(new TestAdapter(this));
// 方式2
//
// groups=new ArrayList<String>();
// groups.add("中国");
// groups.add("美国");
// groups.add("俄罗斯");
//
// children=new ArrayList<ArrayList<String>>();
// ArrayList<String>china=new ArrayList<String>();
// china.add("北京");
// china.add("上海");
// china.add("深圳");
// china.add("海参崴");
// children.add(china);
//
// ArrayList<String>america=new ArrayList<String>();
// america.add("洛杉矶");
// america.add("纽约");
// america.add("芝加哥");
// america.add("迈哈密");
// children.add(america);
//
// ArrayList<String>erous=new ArrayList<String>();
// erous.add("莫斯科");
// erous.add("附加和");
// children.add(erous);
//
// elv_List.setAdapter(new ListDataAdapter(MainActivity.this, groups,
// children));
// 方式3
// values = new LinkedHashMap<String, ArrayList<String>>();
// ArrayList<String> china = new ArrayList<String>();
// china.add("北京");
// china.add("上海");
// china.add("深圳");
// china.add("海参崴");
// values.put("中国", china);
//
// ArrayList<String> erous = new ArrayList<String>();
// erous.add("莫斯科");// erous.add("圣彼得堡");// values.put("俄罗斯", erous); ArrayList<String> america = new ArrayList<String>();// america.add("洛杉矶");// america.add("纽约");// america.add("芝加哥");// america.add("迈哈密");// values.put("美国", america);//
// elv_List.setAdapter(new MapDataAdapter(this, values));}}
4,建立加载数据的Adapter,这里用BaseExpandableListAdapter的实现类来创建,通过adapterpublic Object getChild(int groupPosition, int childPosition) 带的两个参数以及二级列表类似与矩阵,我们可以猜测到二级列表是一个集合成员是集合的集合,表示这种数据的有数组 :数组成员是数组的数组,list集合,成员是集合的集合;那么 adapter的一二级列表数据成员分别是group[],children[]{{}{}};或者grouplist<>,childrenList<List<>>
1)用数组方式实现
package com.cn.testexpansablelist;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseExpandableListAdapter;
import android.widget.TextView;
public class TestAdapter extends BaseExpandableListAdapter {
private GroupViewHolder gHolder;
private LayoutInflater inflater;
private ChildViewHolder cHolder;
private Context context;
private String[] groups = { "People Names", "Dog Names", "Cat Names",
"Fish Names" };
private String[][] children = { { "Arnold", "Barry", "Chuck", "David" },
{ "Ace", "Bandit", "Cha-Cha", "Deuce" }, { "Fluffy", "Snuggles" },
{ "Goldy", "Bubbles" } };
public TestAdapter(Context context) {
this.context = context;
inflater= LayoutInflater.from(context);
}
public int getGroupCount() {
// TODO Auto-generated method stub
return groups.length;
}
public int getChildrenCount(int groupPosition) {
// TODO Auto-generated method stub
return children[groupPosition].length;
}
public Object getGroup(int groupPosition) {
// TODO Auto-generated method stub
return groups[groupPosition];
}
public Object getChild(int groupPosition, int childPosition) {
// TODO Auto-generated method stub
return children[groupPosition][childPosition];
}
public long getGroupId(int groupPosition) {
// TODO Auto-generated method stub
return groupPosition;
}
public long getChildId(int groupPosition, int childPosition) {
// TODO Auto-generated method stub
return childPosition;
}
public boolean hasStableIds() {
// TODO Auto-generated method stub
return false;
}
public View getGroupView(int groupPosition, boolean isExpanded,
View convertView, ViewGroup parent) {
if (convertView == null) {
convertView = inflater.inflate(R.layout.group,
null);
gHolder = new GroupViewHolder();
gHolder.tv_group_name = (TextView) convertView
.findViewById(R.id.tv_group);
convertView.setTag(gHolder);
} else {
gHolder = (GroupViewHolder) convertView.getTag();
}
gHolder.tv_group_name.setText(groups[groupPosition]);
return convertView;
}
public View getChildView(int groupPosition, int childPosition,
boolean isLastChild, View convertView, ViewGroup parent) {
if(convertView==null){
//convertView =inflater.inflate(R.layout.child, null);
convertView=LayoutInflater.from(context).inflate(R.layout.child, null);
cHolder = new ChildViewHolder();
cHolder.tv_contact_name = (TextView) convertView
.findViewById(R.id.tv_child);
convertView.setTag(cHolder);
}else{
cHolder=(ChildViewHolder) convertView.getTag();
}
cHolder.tv_contact_name.setText(children[groupPosition][childPosition]);
return convertView;
}
public boolean isChildSelectable(int groupPosition, int childPosition) {
// TODO Auto-generated method stub
return true;
}
public class GroupViewHolder {
public TextView tv_group_name;
}
public class ChildViewHolder {
public TextView tv_contact_name;
}
}
2)用list方式实现的Adapterpackage com.cn.testexpansablelist;
import java.util.ArrayList;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseExpandableListAdapter;
import android.widget.TextView;
public class ListDataAdapter extends BaseExpandableListAdapter {
private GroupViewHolder gHolder;
private ChildViewHolder cHolder;
private Context context;
private ArrayList<String> groups;
private ArrayList<ArrayList<String>> children;
public ListDataAdapter(Context context, ArrayList<String> groups,
ArrayList<ArrayList<String>> children) {
super();
this.context = context;
this.groups = groups;
this.children = children;
}
public int getGroupCount() {
// TODO Auto-generated method stub
if (groups != null) {
return groups.size();
}
return 0;
}
public int getChildrenCount(int groupPosition) {
// TODO Auto-generated method stub
if (children != null) {
return children.get(groupPosition).size();
}
return 0;
}
public Object getGroup(int groupPosition) {
// TODO Auto-generated method stub
return (groups != null ? groups.get(groupPosition) : null);
// return null;
}
public Object getChild(int groupPosition, int childPosition) {
// TODO Auto-generated method stub
return (children != null ? children.get(groupPosition).get(
childPosition) : null);
}
public long getGroupId(int groupPosition) {
// TODO Auto-generated method stub
return groupPosition;
}
public long getChildId(int groupPosition, int childPosition) {
// TODO Auto-generated method stub
return childPosition;
}
public boolean hasStableIds() {
// TODO Auto-generated method stub
return false;
}
public View getGroupView(int groupPosition, boolean isExpanded,
View convertView, ViewGroup parent) {
//GroupViewHolder gHolder = null;
if (convertView == null) {
convertView = LayoutInflater.from(context).inflate(R.layout.group,
null);
gHolder = new GroupViewHolder();
gHolder.tv_group_name = (TextView) convertView
.findViewById(R.id.tv_group);
convertView.setTag(gHolder);
} else {
gHolder = (GroupViewHolder) convertView.getTag();
}
gHolder.tv_group_name.setText(groups.get(groupPosition));
return convertView;
}
public View getChildView(int groupPosition, int childPosition,
boolean isLastChild, View convertView, ViewGroup parent) {
// ChildViewHolder cHolder = null;
if (convertView == null) {
// convertView =inflater.inflate(R.layout.child, null);
convertView = LayoutInflater.from(context).inflate(R.layout.child,
null);
cHolder = new ChildViewHolder();
cHolder.tv_contact_name = (TextView) convertView
.findViewById(R.id.tv_child);
convertView.setTag(cHolder);
} else {
cHolder = (ChildViewHolder) convertView.getTag();
}
cHolder.tv_contact_name.setText(children.get(groupPosition).get(
childPosition));
return convertView;
}
public boolean isChildSelectable(int groupPosition, int childPosition) {
// TODO Auto-generated method stub
return true;
}
public class GroupViewHolder {
public TextView tv_group_name;
}
public class ChildViewHolder {
public TextView tv_contact_name;
}
}
3),用map方式实现的Adapter,优点不用考虑添加顺序,缺点数据更新是需要重新加载数据;消耗资源。
package com.cn.testexpansablelist;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.LinkedHashMap;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseExpandableListAdapter;
import android.widget.TextView;
public class MapDataAdapter extends BaseExpandableListAdapter {
private Context context;
private LinkedHashMap<String, ArrayList<String>> values;
private ArrayList<String> groups;
private ArrayList<ArrayList<String>> children;
public MapDataAdapter(Context context,
LinkedHashMap<String, ArrayList<String>> values) {
super();
this.context = context;
this.values = values;
initData(values);
}
/**
* 初始化数据
*
* @param values
*/
private void initData(LinkedHashMap<String, ArrayList<String>> values) {
if (values != null) {
this.groups = new ArrayList<String>(values.keySet());
children = new ArrayList<ArrayList<String>>();
for (Iterator<String> it = groups.iterator(); it.hasNext();) {
String key = it.next();
children.add(values.get(key));
}
}
}
public int getGroupCount() {
// TODO Auto-generated method stub
if (groups != null) {
return groups.size();
}
return 0;
}
public int getChildrenCount(int groupPosition) {
// TODO Auto-generated method stub
if (children != null) {
return children.get(groupPosition).size();
}
return 0;
}
public Object getGroup(int groupPosition) {
// TODO Auto-generated method stub
return (groups != null ? groups.get(groupPosition) : null);
// return null;
}
public Object getChild(int groupPosition, int childPosition) {
// TODO Auto-generated method stub
return (children != null ? children.get(groupPosition).get(
childPosition) : null);
}
public long getGroupId(int groupPosition) {
// TODO Auto-generated method stub
return groupPosition;
}
public long getChildId(int groupPosition, int childPosition) {
// TODO Auto-generated method stub
return childPosition;
}
public boolean hasStableIds() {
// TODO Auto-generated method stub
return false;
}
/**
* 如果values的数据发生变化 通知adapter也要跟随改变
*/
public void datachangedNotify(
LinkedHashMap<String, ArrayList<String>> values) {
this.values=values;
initData(values);
notifyDataSetChanged();
}
@Override
public void notifyDataSetChanged() {
// TODO Auto-generated method stub
super.notifyDataSetChanged();
}
public View getGroupView(int groupPosition, boolean isExpanded,
View convertView, ViewGroup parent) {
GroupViewHolder gHolder = null;
if (convertView == null) {
convertView = LayoutInflater.from(context).inflate(R.layout.group,
null);
gHolder = new GroupViewHolder();
gHolder.tv_group_name = (TextView) convertView
.findViewById(R.id.tv_group);
convertView.setTag(gHolder);
} else {
gHolder = (GroupViewHolder) convertView.getTag();
}
gHolder.tv_group_name.setText(groups.get(groupPosition));
return convertView;
}
public View getChildView(int groupPosition, int childPosition,
boolean isLastChild, View convertView, ViewGroup parent) {
ChildViewHolder cHolder = null;
if (convertView == null) {
// convertView =inflater.inflate(R.layout.child, null);
convertView = LayoutInflater.from(context).inflate(R.layout.child,
null);
cHolder = new ChildViewHolder();
cHolder.tv_contact_name = (TextView) convertView
.findViewById(R.id.tv_child);
convertView.setTag(cHolder);
} else {
cHolder = (ChildViewHolder) convertView.getTag();
}
cHolder.tv_contact_name.setText(children.get(groupPosition).get(
childPosition));
return convertView;
}
public boolean isChildSelectable(int groupPosition, int childPosition) {
// TODO Auto-generated method stub
return true;
}
public class GroupViewHolder {
public TextView tv_group_name;
}
public class ChildViewHolder {
public TextView tv_contact_name;
}
}
以上方式仅供参考。demo地址:TestExpansableList.rar