多级列表——ExpandableListView
2015-08-12 13:52
316 查看
ExpandableListView控件提供的是一个多级列表(一般是两级),我们先来看一下效果图,如图4.18所示为头部列表,单击其中的每一项下面会显示第二级列表,如图4.19所示。
从图4.18和图4.19中可以看出,ExpandableListView为我们提供了一个极好的两级列表的展示控件。
但是如何实现这个两级列表呢?既然ExpandableListView采用列表的形式,它也应该有一个适配器,但是它的适配器不是继承
BaseAdapter,而是要继承它独有的适配器BaseExpandableListAdapter,同时也需要实现其中的几个方法,如表4.3所
示。
表4.3 BaseExpandableListAdapter中的方法
表4.3简单地介绍了BaseExpandableListAdapter中的方法,下面来实现图4.18和图4.19中的效果。
(1)布局文件。从图中可以看出我们需要用到3个布局文件:一个是声明ExpandableListView,一个声明第一级菜单,一个是第二级菜单的布局文件。
声明ExpandableListView的布局文件:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="fill_parent"
android:layout_height="fill_parent" android:background="@drawable/default_bg">
<ExpandableListView android:id="@+id/list"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_alignParentLeft="true"/>
</RelativeLayout>
第一级菜单布局文件:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="40dip"
android:layout_gravity="center_horizontal" >
<LinearLayout
android:id="@+id/layout_013"
android:layout_width="fill_parent"
android:layout_height="40dip"
android:orientation="horizontal" >
<ImageView
android:id="@+id/ImageView01"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center_vertical"
android:paddingTop="10dip"
android:src="@drawable/user_group" >
</ImageView>
<RelativeLayout
android:id="@+id/layout_013"
android:layout_width="wrap_content"
android:layout_height="wrap_content" >
<TextView
android:id="@+id/content_001"
android:layout_width="wrap_content"
android:layout_height="fill_parent"
android:layout_gravity="center_vertical"
android:gravity="center_vertical"
android:paddingLeft="10px"
android:textColor="#FFFFFF"
android:textSize="26px" >
</TextView>
<ImageView
android:id="@+id/tubiao"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true" >
</ImageView>
</RelativeLayout>
</LinearLayout>
</LinearLayout>
第二级菜单布局文件:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/childlayout"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="horizontal" >
<ImageView
android:id="@+id/child_image"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="40dip"
android:background="@drawable/child_image"
android:paddingTop="10dip" >
</ImageView>
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical" >
<TextView
android:id="@+id/child_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:gravity="center_vertical"
android:text=""
android:textSize="16dip" >
</TextView>
<TextView
android:id="@+id/child_text2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:gravity="center_vertical"
android:text=""
android:textSize="12dip" >
</TextView>
</LinearLayout>
</LinearLayout>
(2)写一个类ExAdapter继承BaseExpandableListAdapter,并且实现它的方法。获取给定组的一个显示的视图:
//获取一个显示的视图给定组
public View getGroupView(int groupPosition, boolean isExpanded,
View convertView, ViewGroup parent) {
View view = convertView;
if (view == null) {
// 通过getSystemService方法实例化一个视图的填充器
LayoutInflater inflater = (LayoutInflater) getSystemService
(Context.LAYOUT_INFLATER_SERVICE);
view = inflater.inflate(R.layout.member_listview, null);
}
TextView title = (TextView) view.findViewById
(R.id.content_001);
title.setText(getGroup(groupPosition).toString());
ImageView image=(ImageView) view.findViewById(R.id.tubiao);
//判断实例可以展开,如果可以则改变右侧的图标
if(isExpanded)
image.setBackgroundResource(R.drawable.btn_browser2);
else image.setBackgroundResource(R.drawable.btn_browser);
return view;
}
获取给定组的相关数据及显示的列数:
//获取给定组相关的数据
public Object getGroup(int groupPosition) {
return groupData.get(groupPosition).get(G_TEXT).toString();
}
//获取第一级列表的列数
public int getGroupCount() {
return groupData.size();
}
获取一个视图显示在给定的组的孩子的数据:
public View getChildView(int groupPosition, int childPosition,
boolean isLastChild, View convertView, ViewGroup parent) {
View view = convertView;
if (view == null) {
//填充视图
LayoutInflater inflater = (LayoutInflater) getSystemService
(Context.LAYOUT_INFLATER_SERVICE);
view = inflater.inflate(R.layout.member_childitem, null);
}
final TextView title = (TextView) view.findViewById
(R.id.child_text);
title.setText(childData.get(groupPosition).
get(childPosition).get(C_TEXT1).toString());
final TextView title2 = (TextView) view.findViewById
(R.id.child_text2);
title2.setText(childData.get(groupPosition).
get(childPosition).get(C_TEXT2).toString());
return view;
}
获取与孩子在给定的组相关的数据,以及孩子组显示的列数:
//获取与孩子在给定的组相关的数据
public Object getChild(int groupPosition, int childPosition) {
return childData.get(groupPosition).get(childPosition).get(C_TEXT1).toString();
}
//获取指定组中孩子的数量
public int getChildrenCount(int groupPosition) {
return childData.get(groupPosition).size();
}
(3)通过方法findViewById获取ExpandableListView的实例,为其设置数据显示的适配器。
for (int i = 0; i < 5; i++) {
Map<String, String> curGroupMap = new HashMap<String, String>();
groupData.add(curGroupMap);
curGroupMap.put(G_TEXT, "Group " + i);
List<Map<String, String>> children = new ArrayList<Map<String, String>>();
for (int j = 0; j < 5; j++) {
Map<String, String> curChildMap = new HashMap<String, String>();
children.add(curChildMap);
curChildMap.put(C_TEXT1, "Child " + j);
curChildMap.put(C_TEXT2, "Child " + j);
}
childData.add(children);
}
adapter=new ExAdapter(ExpanListViewDemoActivity.this);
exList = (ExpandableListView) findViewById(R.id.list);
exList.setAdapter(adapter);
exList.setGroupIndicator(null);
exList.setDivider(null);
从这个实例中可以看到,ExpandableListView的功能主要在于它的适配器,只要写好了适配器,列表就会显示出来。上面的例子中,我们
没有添加,单击第二级列表不会有任何反应,如果要有点击的效果,需要为ExpandableListView设置一个事
件:setOnChildClickListener,实例化OnChildClickListener类,实现其中的public boolean
onChildClick(ExpandableListView parent, View v,int groupPosition, int
childPosition, long id)方法,这个事件就留给读者去实现。
从图4.18和图4.19中可以看出,ExpandableListView为我们提供了一个极好的两级列表的展示控件。
但是如何实现这个两级列表呢?既然ExpandableListView采用列表的形式,它也应该有一个适配器,但是它的适配器不是继承
BaseAdapter,而是要继承它独有的适配器BaseExpandableListAdapter,同时也需要实现其中的几个方法,如表4.3所
示。
表4.3 BaseExpandableListAdapter中的方法
方法名称 | 参数 | 说明 |
getGroupId | int groupPosition | 获取组在给定的位置编号 |
getChildId | int groupPosition, int childPosition | 获取给定组的孩子的ID |
getGroupCount | 获取第一级列表的列数 | |
getChildrenCount | int groupPosition | 获取指定组中孩子的数量 |
getGroup | int groupPosition | 获取给定组相关的数据 |
getGroupView | int groupPosition, boolean isExpanded, View convertView, ViewGroup parent | 获取一个显示的视图给定组 |
getChild | int groupPosition, int childPosition | 获取与孩子在给定的组相关的数据 |
getChildView | int groupPosition, int childPosition, boolean isLastChild, View convertView, ViewGroup parent | 获取一个视图显示在给定的组的孩子的数据 |
(1)布局文件。从图中可以看出我们需要用到3个布局文件:一个是声明ExpandableListView,一个声明第一级菜单,一个是第二级菜单的布局文件。
声明ExpandableListView的布局文件:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="fill_parent"
android:layout_height="fill_parent" android:background="@drawable/default_bg">
<ExpandableListView android:id="@+id/list"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_alignParentLeft="true"/>
</RelativeLayout>
第一级菜单布局文件:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="40dip"
android:layout_gravity="center_horizontal" >
<LinearLayout
android:id="@+id/layout_013"
android:layout_width="fill_parent"
android:layout_height="40dip"
android:orientation="horizontal" >
<ImageView
android:id="@+id/ImageView01"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center_vertical"
android:paddingTop="10dip"
android:src="@drawable/user_group" >
</ImageView>
<RelativeLayout
android:id="@+id/layout_013"
android:layout_width="wrap_content"
android:layout_height="wrap_content" >
<TextView
android:id="@+id/content_001"
android:layout_width="wrap_content"
android:layout_height="fill_parent"
android:layout_gravity="center_vertical"
android:gravity="center_vertical"
android:paddingLeft="10px"
android:textColor="#FFFFFF"
android:textSize="26px" >
</TextView>
<ImageView
android:id="@+id/tubiao"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true" >
</ImageView>
</RelativeLayout>
</LinearLayout>
</LinearLayout>
第二级菜单布局文件:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/childlayout"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="horizontal" >
<ImageView
android:id="@+id/child_image"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="40dip"
android:background="@drawable/child_image"
android:paddingTop="10dip" >
</ImageView>
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical" >
<TextView
android:id="@+id/child_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:gravity="center_vertical"
android:text=""
android:textSize="16dip" >
</TextView>
<TextView
android:id="@+id/child_text2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:gravity="center_vertical"
android:text=""
android:textSize="12dip" >
</TextView>
</LinearLayout>
</LinearLayout>
(2)写一个类ExAdapter继承BaseExpandableListAdapter,并且实现它的方法。获取给定组的一个显示的视图:
//获取一个显示的视图给定组
public View getGroupView(int groupPosition, boolean isExpanded,
View convertView, ViewGroup parent) {
View view = convertView;
if (view == null) {
// 通过getSystemService方法实例化一个视图的填充器
LayoutInflater inflater = (LayoutInflater) getSystemService
(Context.LAYOUT_INFLATER_SERVICE);
view = inflater.inflate(R.layout.member_listview, null);
}
TextView title = (TextView) view.findViewById
(R.id.content_001);
title.setText(getGroup(groupPosition).toString());
ImageView image=(ImageView) view.findViewById(R.id.tubiao);
//判断实例可以展开,如果可以则改变右侧的图标
if(isExpanded)
image.setBackgroundResource(R.drawable.btn_browser2);
else image.setBackgroundResource(R.drawable.btn_browser);
return view;
}
获取给定组的相关数据及显示的列数:
//获取给定组相关的数据
public Object getGroup(int groupPosition) {
return groupData.get(groupPosition).get(G_TEXT).toString();
}
//获取第一级列表的列数
public int getGroupCount() {
return groupData.size();
}
获取一个视图显示在给定的组的孩子的数据:
public View getChildView(int groupPosition, int childPosition,
boolean isLastChild, View convertView, ViewGroup parent) {
View view = convertView;
if (view == null) {
//填充视图
LayoutInflater inflater = (LayoutInflater) getSystemService
(Context.LAYOUT_INFLATER_SERVICE);
view = inflater.inflate(R.layout.member_childitem, null);
}
final TextView title = (TextView) view.findViewById
(R.id.child_text);
title.setText(childData.get(groupPosition).
get(childPosition).get(C_TEXT1).toString());
final TextView title2 = (TextView) view.findViewById
(R.id.child_text2);
title2.setText(childData.get(groupPosition).
get(childPosition).get(C_TEXT2).toString());
return view;
}
获取与孩子在给定的组相关的数据,以及孩子组显示的列数:
//获取与孩子在给定的组相关的数据
public Object getChild(int groupPosition, int childPosition) {
return childData.get(groupPosition).get(childPosition).get(C_TEXT1).toString();
}
//获取指定组中孩子的数量
public int getChildrenCount(int groupPosition) {
return childData.get(groupPosition).size();
}
(3)通过方法findViewById获取ExpandableListView的实例,为其设置数据显示的适配器。
for (int i = 0; i < 5; i++) {
Map<String, String> curGroupMap = new HashMap<String, String>();
groupData.add(curGroupMap);
curGroupMap.put(G_TEXT, "Group " + i);
List<Map<String, String>> children = new ArrayList<Map<String, String>>();
for (int j = 0; j < 5; j++) {
Map<String, String> curChildMap = new HashMap<String, String>();
children.add(curChildMap);
curChildMap.put(C_TEXT1, "Child " + j);
curChildMap.put(C_TEXT2, "Child " + j);
}
childData.add(children);
}
adapter=new ExAdapter(ExpanListViewDemoActivity.this);
exList = (ExpandableListView) findViewById(R.id.list);
exList.setAdapter(adapter);
exList.setGroupIndicator(null);
exList.setDivider(null);
从这个实例中可以看到,ExpandableListView的功能主要在于它的适配器,只要写好了适配器,列表就会显示出来。上面的例子中,我们
没有添加,单击第二级列表不会有任何反应,如果要有点击的效果,需要为ExpandableListView设置一个事
件:setOnChildClickListener,实例化OnChildClickListener类,实现其中的public boolean
onChildClick(ExpandableListView parent, View v,int groupPosition, int
childPosition, long id)方法,这个事件就留给读者去实现。
相关文章推荐
- 学习的逻辑
- 设置html页面不被浏览器缓存
- html实体转换
- Android实战技巧之三十三:android.hardware.camera2使用指南
- svm tips
- Android之用PopupWindow实现弹出listview形式菜单
- Python学习笔记09
- firefox浏览器删除插件
- CentOS---tftp(安装、配置、使用)
- PHP_PHP操作Word-PHPWord
- Android登录拦截器实现方式(一)
- CSS浮动(float,clear)通俗讲解
- 安全驾驶-高速路倒车(二二)
- 安全驾驶-线路规划(二一)
- tomcat sso 配置
- [hdu5373 The shortest problem]模拟
- iOS 之单例,代理,通知,KVO,Block全能解析
- 9、SQL Server 操作数据
- jQuery中的.bind()、.live()和.delegate()之间区别分析
- 文本溢出显示省略号