ExpandableListView扩展(BaseExpandableListAdapter的使用)

article/2025/11/4 8:51:36

针对普通的ExpandableListView的使用,即,需要显示的数据全都是使用TextView显示时,我们使用SimpleExpandableListAdapter就可以了。

但是如果是相对复杂的ExpandableListView,那么SimpleExpandableListAdapter就不满足我们的要求。

例如:在ExpandableListView中使用CheckBox控件。

这时候,我们就必须自己写一个Adapter来使用。方法是继承BaseExpandableListAdapter

 

layout/main.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" 
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<ExpandableListView 
android:id="@id/android:list"
android:layout_width="fill_parent" 
android:layout_height="fill_parent">
</ExpandableListView>
<TextView 
android:layout_width="fill_parent"
android:layout_height="fill_parent" 
android:id="@id/android:empty"
android:text="No Data" />
</LinearLayout>


layout/groups.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" 
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView 
android:id="@+id/groupTextView"
android:layout_width="fill_parent"
android:layout_height="fill_parent" 
android:textSize="25sp" 
android:paddingLeft="35px" 
android:paddingTop="10px"
android:paddingRight="5px" 
android:paddingBottom="10px" 
android:text="No Data" />
</LinearLayout>


layout/childs.xml(其实英文名字应该是children才对)

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView 
android:id="@+id/childTextView"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_alignParentLeft="true"
android:textSize="22sp"
android:layout_marginLeft="30dip"
android:layout_marginTop="5dip"
android:text="No Data" />
<CheckBox 
android:id="@+id/childCheckBox"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_alignParentRight="true"
android:layout_marginLeft="50dip"/>
</RelativeLayout>


主类ExpandableListViewActivity.java

package com.zeph.android.expandablelistview.example;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import android.app.ExpandableListActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.ExpandableListView;
public class ExpandableListViewActivity extends ExpandableListActivity {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
// 创建两个一级条目标题
List<Map<String, String>> groupData = new ArrayList<Map<String, String>>();
Map<String, String> groupData1 = new HashMap<String, String>();
groupData1.put("groupTextView", "新闻");// group对应layout中的id:group
Map<String, String> groupData2 = new HashMap<String, String>();
groupData2.put("groupTextView", "科技");
groupData.add(groupData1);
groupData.add(groupData2);
// 创建第一个一级条目下的的二级条目
List<Map<String, Object>> child1 = new ArrayList<Map<String, Object>>();
Map<String, Object> childData1 = new HashMap<String, Object>();
childData1.put("childTextView", "网易头条新闻");// 同理
childData1.put("childCheckBox", 0);// 同理
Map<String, Object> childData2 = new HashMap<String, Object>();
childData2.put("childTextView", "凤凰网新闻");
childData2.put("childCheckBox", 1);
child1.add(childData1);
child1.add(childData2);
// 创建第二个一级条目下的的二级条目
List<Map<String, Object>> child2 = new ArrayList<Map<String, Object>>();
Map<String, Object> childData3 = new HashMap<String, Object>();
childData3.put("childTextView", "TechWeb");
childData3.put("childCheckBox", 0);
Map<String, Object> childData4 = new HashMap<String, Object>();
childData4.put("childTextView", "月光博客");
childData4.put("childCheckBox", 1);
child2.add(childData3);
child2.add(childData4);
// 将二级条目放在一个集合里,供显示时使用
List<List<Map<String, Object>>> childData = new ArrayList<List<Map<String, Object>>>();
childData.add(child1);
childData.add(child2);
MyExpandableListViewAdapter adapter = new MyExpandableListViewAdapter(
getApplicationContext(), groupData, R.layout.groups,
new String[] { "groupTextView" },
new int[] { R.id.groupTextView }, childData, R.layout.childs,
new String[] { "childTextView", "childCheckBox" }, new int[] {
R.id.childTextView, R.id.childCheckBox });
setListAdapter(adapter);
}
/**
* 设置哪个二级目录被默认选中
*/
@Override
public boolean setSelectedChild(int groupPosition, int childPosition,
boolean shouldExpandGroup) {
// do something
return super.setSelectedChild(groupPosition, childPosition,
shouldExpandGroup);
}
/**
* 设置哪个一级目录被默认选中
*/
@Override
public void setSelectedGroup(int groupPosition) {
// do something
super.setSelectedGroup(groupPosition);
}
/**
* 当二级条目被点击时响应
*/
@Override
public boolean onChildClick(ExpandableListView parent, View v,
int groupPosition, int childPosition, long id) {
// do something
return super.onChildClick(parent, v, groupPosition, childPosition, id);
}
}


Adapter类,MyExpandableListViewAdapter.java

package com.zeph.android.expandablelistview.example;
import java.util.List;
import java.util.Map;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseExpandableListAdapter;
import android.widget.CheckBox;
import android.widget.TextView;
/**
* 首个List对应子元素中所代表的组,第二个List对应孙子元素在子元素组中的位置. Map亦将支持这样的特殊元素。(子元素嵌套组元素的情况)
* 将XML文件中定义的静态数据映射到组及其视图的简单的适配器. 你可以用 Map的列表,为组指定其后台数据。每个数组元素对应一个可展开列表的一个组。
* Maps 包含每行的数据。你还可以指定 XML 文件来定义用于显示组的视图, 并通过 Map 的键值映射到指定的视图。该过程适用于组的子元素。
* 单级以外的可展开列表的后台数据类型为List<List<Map>>,
* 第一级列表对应可扩展视图组中的组视图,第二级列表对应组的子组视图, 最后 Map 保持子组视图的子视图的数据。
* 
* @author BenZeph (以下代码和注释均参考了工具屋,网址:http://code.google.com/p/toolib/)
*/
public class MyExpandableListViewAdapter extends BaseExpandableListAdapter {
private List<? extends Map<String, ?>> mGroupData;
private int mExpandedGroupLayout;
private int mCollapsedGroupLayout;
private String[] mGroupFrom;
private int[] mGroupTo;
private List<? extends List<? extends Map<String, ?>>> mChildData;
private int mChildLayout;
private int mLastChildLayout;
private String[] mChildFrom;
private int[] mChildTo;
private LayoutInflater mInflater;
/**
* 调用另外一个构造函数,其中From和To的含义和不同的ListView相同,
* 可以参考ListView或者SimpleExpandableListViewAdapter
* 
* @param context
* @param groupData
* @param groupLayout
* @param groupFrom
* @param groupTo
* @param childData
* @param childLayout
* @param childFrom
* @param childTo
*/
public MyExpandableListViewAdapter(Context context,
List<? extends Map<String, ?>> groupData, int groupLayout,
String[] groupFrom, int[] groupTo,
List<? extends List<? extends Map<String, ?>>> childData,
int childLayout, String[] childFrom, int[] childTo) {
this(context, groupData, groupLayout, groupLayout, groupFrom, groupTo,
childData, childLayout, childLayout, childFrom, childTo);
}
/**
* 
* @param context
* @param groupData
* @param expandedGroupLayout
* @param collapsedGroupLayout
* @param groupFrom
* @param groupTo
* @param childData
* @param childLayout
* @param lastChildLayout
* @param childFrom
* @param childTo
*/
public MyExpandableListViewAdapter(Context context,
List<? extends Map<String, ?>> groupData, int expandedGroupLayout,
int collapsedGroupLayout, String[] groupFrom, int[] groupTo,
List<? extends List<? extends Map<String, ?>>> childData,
int childLayout, int lastChildLayout, String[] childFrom,
int[] childTo) {
mGroupData = groupData;
mExpandedGroupLayout = expandedGroupLayout;
mCollapsedGroupLayout = collapsedGroupLayout;
mGroupFrom = groupFrom;
mGroupTo = groupTo;
mChildData = childData;
mChildLayout = childLayout;
mLastChildLayout = lastChildLayout;
mChildFrom = childFrom;
mChildTo = childTo;
mInflater = (LayoutInflater) context
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
@Override
public Object getChild(int groupPosition, int childPosition) {
// 取得与指定分组、指定子项目关联的数据。
return mChildData.get(groupPosition).get(childPosition);
}
@Override
public long getChildId(int groupPosition, int childPosition) {
// 取得给定分组中给定子视图的ID。 该组ID必须在组中是唯一的。组合的ID (参见getCombinedGroupId(long))
// 必须不同于其他所有ID(分组及子项目的ID)。
return childPosition;
}
@Override
public View getChildView(int groupPosition, int childPosition,
boolean isLastChild, View convertView, ViewGroup parent) {
// 取得显示给定分组给定子位置的数据用的视图。
View v;
if (convertView == null) {
v = newChildView(isLastChild, parent);
} else {
v = convertView;
}
bindChildView(v, mChildData.get(groupPosition).get(childPosition),
mChildFrom, mChildTo);
return v;
}
@Override
public int getChildrenCount(int groupPosition) {
// 取得指定分组的子元素数。
return mChildData.get(groupPosition).size();
}
@Override
public Object getGroup(int groupPosition) {
// 取得与给定分组关联的数据。
return mGroupData.get(groupPosition);
}
@Override
public int getGroupCount() {
// 取得分组数
return mChildData.size();
}
@Override
public long getGroupId(int groupPosition) {
// 取得指定分组的ID。该组ID必须在组中是唯一的。组合的ID (参见getCombinedGroupId(long))
// 必须不同于其他所有ID(分组及子项目的ID)。
return groupPosition;
}
@Override
public View getGroupView(int groupPosition, boolean isExpanded,
View convertView, ViewGroup parent) {
// 取得用于显示给定分组的视图。 这个方法仅返回分组的视图对象, 要想获取子元素的视图对象,
// 就需要调用 getChildView(int, int, boolean, View, ViewGroup)。
View v;
if (convertView == null) {
v = newGroupView(isExpanded, parent);
} else {
v = convertView;
}
bindGroupView(v, mGroupData.get(groupPosition), mGroupFrom, mGroupTo);
return v;
}
@Override
public boolean hasStableIds() {
// 是否指定分组视图及其子视图的ID对应的后台数据改变也会保持该ID。
return true;
}
@Override
public boolean isChildSelectable(int groupPosition, int childPosition) {
// 指定位置的子视图是否可选择。
return true;
}
/**
* 创建新的组视图
* 
* @param isExpanded
* @param parent
* @return
*/
public View newGroupView(boolean isExpanded, ViewGroup parent) {
return mInflater.inflate((isExpanded) ? mExpandedGroupLayout
: mCollapsedGroupLayout, parent, false);
}
/**
* 创建新的子视图
* 
* @param isLastChild
* @param parent
* @return
*/
public View newChildView(boolean isLastChild, ViewGroup parent) {
return mInflater.inflate((isLastChild) ? mLastChildLayout
: mChildLayout, parent, false);
}
/**
* 绑定组数据
* 
* @param view
* @param data
* @param from
* @param to
*/
private void bindGroupView(View view, Map<String, ?> data, String[] from,
int[] to) {
// 绑定组视图的数据,针对Group的Layout都是TextView的情况
int len = to.length;
for (int i = 0; i < len; i++) {
TextView v = (TextView) view.findViewById(to[i]);
if (v != null) {
v.setText((String) data.get(from[i]));
}
}
}
/**
* 绑定子数据
* 
* @param view
* @param data
* @param from
* @param to
*/
private void bindChildView(View view, Map<String, ?> data, String[] from,
int[] to) {
TextView v = (TextView) view.findViewById(to[0]);
if (v != null) {
v.setText((String) data.get(from[0]));
}
CheckBox c = (CheckBox) view.findViewById(to[1]);
if (c != null) {
if (data.get(from[1]).equals(0)) {
c.setChecked(true);
} else {
c.setChecked(false);
}
}
}
}


 

程序本身还存在问题,checkbox在点击修改了状态之后,缩小组,在展开组,checkbox的状态会还原。

这是因为,在点击展开时,会重新调用getChildView函数,于是子列表的中的数据重新初始化了。所以数据就还原了。

因此,这个位置的代码还需要修改。才能满足要求。

 

 

 

 

 

 


http://chatgpt.dhexx.cn/article/8ybUbnqa.shtml

相关文章

ExpandableListView控件的使用

目录 一、ExpandableListView的介绍 二、适配器&#xff08;ExpandableAdapter&#xff09; 1、BaseExpandableListAdapter&#xff1a; BaseExpandableListAdapter例子 一、ExpandableListView的介绍 ExpandableListView是ListView的子类。它是ListView的基础上进行了扩展&…

ExpandableListView的使用详解

在Android开发中&#xff0c;我们知道经常会用到ListView来加载一些列表数据&#xff0c;但有时候ListView并不能完全十分满足我们的需求。比如如下图的效果用 ExpandableListView实现起来就更方便点&#xff0c;我们直接用ExpandableListView&#xff0c;设置Group不能点击即可…

ExpandableListView实例

先来看效果图&#xff1a; demo中有三个group item和多个child item&#xff0c;group item包括一个指示器&#xff0c;一个标题和一个按钮。child item包括一个图片&#xff0c;一个标题和一个按钮。先来实现布局文件 1 activity_main.xml <?xml version"1.0&qu…

ExpandableListView使用方法详解

一、前言 “好记性不如烂笔头”&#xff0c;再次验证了这句话是真的很有道理啊&#xff0c;一个月前看了一下ExpandableListView的使用&#xff0c;今天再看居然忘了这个是干啥的了&#xff0c;今天就详细讲解一下ExpandableListView的使用方法&#xff0c;感觉对于二级条目显示…

ExpandableList的使用

首先&#xff0c;我们把一二级选择的对应的类写好。 看这些代码&#xff0c;最主要的是我在ParentStrings中写了一个List<ChildrenStrings>的一个方法&#xff0c;以便之后ChildrenStrings的存储和调用 下面是BusAdapter继承BaseExpandableAdapter public class BusAda…

可折叠列表ExpandableList

ExpandableList就是可展开的ListView 首先我们来看一下页面的布局 expandlist_layout.xml文件 <RelativeLayoutxmlns:android"http://schemas.android.com/apk/res/android"xmlns:app"http://schemas.android.com/apk/res-auto"xmlns:tools"htt…

Adapter类控件使用之ExpandableList(可折叠式列表)的基本使用

(一)概述 本节要讲解的Adapter类控件是ExpandableListView,就是可折叠的列表,它是 ListView的子类, 在ListView的基础上它把应用中的列表项分为几组,每组里又可包含多个列表项。至于 样子, 类似于QQ联系人列表,他的用法与ListView非常相似,只是ExpandableListViv…

如果在临汾遇见你

哈 如果在临汾遇见你&#xff0c;那么&#xff0c;我们一定要去平阳南街煤化巷口的宾库西餐厅&#xff0c;坐在只需消费15块钱就可以坐一整天的大厅散座上&#xff0c;聊着我们相见恨晚的话题。 如果在临汾遇见你&#xff0c;那么&#xff0c;我们一定要去传说的尧庙&#xff0…

吃完7家互联网大厂食堂,我回去就把老板开了

本文转载自 超人测评 不会还有人不知道&#xff08;中文&#xff09;字节跳动&#xff08;英文&#xff09;Bytedance的工牌&#xff0c;已经成为年轻人的社交货币了吧。 有人说它是“相亲市场的硬通货”&#xff0c;也有人将它称为“2021年最潮流时尚单品”。每当你在奶茶店…

围剿宏光MINI

NEW 关注Tech逆向思维视频号 最新视频→【做核酸&#xff1f;打疫苗&#xff1f;3分钟假期安全出行攻略】 出品&#xff5c;深途 文&#xff5c;黎明 编辑&#xff5c; 魏佳 有很长一段时间&#xff0c;汽车企业的老板和投资人&#xff0c;都热衷于造“大车”。蔚来、小鹏、威马…

《植物大战僵尸》的12个成功秘诀

口述 / James Gwertzman 整理 / 杨东杰 [caption id"attachment_6675" align"alignleft" width"263" caption"James Gwertzman PopCap亚太区总裁"] [/caption] 4月28日&#xff0c;在由长城会和CSDN联合主办的“开发者星球——TUP大…

只要10分钟,搭建属于个人的炫酷网站,你还在犹豫什么?

&#x1f482; 个人主页: IT学习日记&#x1f91f; 版权: 本文由【IT学习日记】原创、在CSDN首发、需要转载请联系博主&#x1f4ac; 如果文章对你有帮助、欢迎关注、点赞、收藏(一键三连)和订阅专栏哦&#x1f485; 想寻找共同成长的小伙伴&#xff0c;请点击【技术圈子】 文章…

我的股票投资原则:专注业绩好、看得懂的消费品行业

本文概要&#xff1a;文以载道。总结了过往的经验教训&#xff0c;明确了未来的投资方向和股票投资圈。 我是一名Java程序员&#xff0c;今年心情有点烦躁&#xff0c;没怎么有耐心写工作之外的代码。 同时&#xff0c;我也是一名业余投资人&#xff0c;所以今年就又花了大量…

最近回了趟家,随便拍的照片

先贴下家对面的东山。呵呵。看上去光秃秃的。不过我看上去只有很深的亲切。 家里盖被子的东西 我大哥房间里面别人送的&#xff0d;&#xff0d;&#xff0d;堆绣  是我们湟中的一种农民搞的艺术品 家里的酸奶。  呵呵&#xff0c;大家很多人都记得西宁街头的那种勺子挖着…

破解网址_中国目前的破解组织大全

中国目前的破解组织大全&#xff08;2009版&#xff09;——[TFW]find31作品 管理提醒&#xff1a; 本帖被 朕很伤心 从 『 风云AD区 』 移动到本区(2009-06-23) 破解组织前管理员告诉你中国目前的破解组织现状——看了某个N年前的帖子而发&#xff0c;说实话我真的不忍心再看…

推荐 10 个不错的网络监视工具

点击上方“民工哥技术之路”选择“置顶或星标” 每天10点为你分享不一样的干货 有几个网络监视工具可以用于不同的操作系统。在这篇文章中&#xff0c;我们将讨论从 Linux 终端中运行的 10 个网络监视工具。 它对不使用 GUI 而希望通过 SSH 来保持对网络管理的用户来说是非常理…

【Java】Socket网络编程实现内网穿透、端口映射转发、内网穿透上网工具的编写,设置IP白名单防火墙

这里写目录标题 简介更新 一、背景1.1 情景假设1.2 想要达到的目的1.3 局限1.3 解决方案一&#xff08;路由器NAT&#xff09;1.4 解决方案二&#xff08;云服务器转发&#xff09; 二、方案介绍2.1 方案简介2.2 具体流程2.3 编程要点2.4 关于web管理IP白名单的更新2.5 关于soc…

计算机网络--Windows网络测试工具

实验目的 理解上述知识点所涉及的基本概念并学会使用这些工具测试网络的状态及从网上获取信息。 实验环境 安装了TCP/IP协议的Windows系统&#xff0c;包含实用的网络工具。 实验内容 完成下列要求&#xff0c;并记录实验步骤和结果 1、 检测本机的MAC地址 2、 检测本机网…

【小工具的制作】制作一个通过HTTP请求来实现上网认证的自动登录小工具

目录 1. 前言2. 分析3. 编码3.1 Python版3.1.1 编写Python脚本3.1.2 下载Python转EXE程序工具3.1.3 打包成EXE程序 3.2 Java版3.2.1 编写代码 4. 最后一步5. 总结 1. 前言 由于学校机房联网时&#xff0c;总是需要登录个人账号。为实现快速登录&#xff0c;我们就此问题给出了自…

常见的网络抓包工具推荐

因为发现好多人想抓包&#xff0c;但是不知道有哪些工具&#xff0c;今天我给大家推荐几款抓包工具&#xff0c;希望对大家有所帮助。 网络抓包工具的用途 网络抓包工具的主要功能是将网络执行的过程&#xff0c;详细的记录下来。如果你是一个程序员&#xff0c;肯定对网络抓…