ExpandableListView可扩展列表视图,可折叠列表视图

news2024/10/7 14:23:59

目录

1. XML代码

2. ExpandableListView的使用

3. ExpandableListAdapter的使用

4. 数据观察者的使用

5. 案例代码一览


ExpandableListView(可扩展/可折叠列表视图)是一种多功能的高级控件,每个子项都可以展开一个孙子列表。点击一个分组(子项),即可展开该分组下的孙子列表;再次点击该分组,即可收起该分组下的孙子项列表。

1. XML代码

<ExpandableListView
    android:id="@+id/expandableListView"
    android:layout_width="match_parent"
    android:layout_height="match_parent"/>

2. ExpandableListView的使用

可折叠列表视图的常用方法说明:

  • setAdapter:设置适配器。适配器类型为ExpandableListAdapter。
  • expandGroup:展开指定分组。
  • collapseGroup:收起指定分组。
  • isGroupExpanded:判断指定分组是否展开。
  • setSelectedGroup:设置选中的分组。
  • setSelectedChild:设置选中的孙子项。
  • setGroupIndicator:设置指定分组的指示图像。
  • setChildIndicator:设置指定孙子项的指示图像。
  • setOnGroupExpandListener:设置分组展开监听器。需实现接口 OnGroupExpandListener的onGroupExpand方法,该方法在点击展开分组时触发。
  • setOnGroupCollapseListener:设置分组收起监听器。需实现接口 OnGroupCollapseListener的onGroupCollapse方法,该方法在点击收起分组时触发。
  • setOnGroupClickListener:设置分组点击监听器。需实现接口 OnGroupClickListener 的onGroupClick方法,该方法在点击分组时触发。
  • setOnChildClickListener:设置孙子项点击监听器。需实现接口 OnChildClickListener 的onChildClick方法,该方法在点击孙子项时触发。

3. ExpandableListAdapter的使用

可折叠列表视图拥有专属的适配器ExpandableListAdapter(可折叠列表适配器)。

下面是该适配器经常要重写的5个方法:

  • getGroupCount:获取分组的个数。
  • getChildrenCount:获取孙子项的个数。
  • getGroupView:获取指定分组的视图。
  • getChildView:获取指定孙子项的视图。
  • isChildSelectable:判断孙子项是否允许选择。

全部方法使用说明如下所示:

class MyAdapter implements ExpandableListAdapter {
    DataSetObserver dataSetObserver;
    public MyAdapter(){
        //构造方法,可以在参数中进行数据传入
    }
    //注册数据观察者
    public void registerDataSetObserver(DataSetObserver dataSetObserver) {
        this.dataSetObserver=dataSetObserver;
    }
    //注销数据观察者
    public void unregisterDataSetObserver(DataSetObserver dataSetObserver) {
        dataSetObserver=null;
    }
    //返回父项的数量,即可展开列表中的组数
    public int getGroupCount() {
        return 0;
    }
    //返回特定组(父项)中子项的数量
    public int getChildrenCount(int i) {
        return 0;
    }
    //返回指定位置的父项对象
    public Object getGroup(int i) {
        return null;
    }
    //返回指定位置的子项对象
    public Object getChild(int i, int i1) {
        return null;
    }
    //返回指定位置的父项的唯一标识符
    public long getGroupId(int i) {
        return 0;
    }
    //返回指定位置的子项的唯一标识符
    public long getChildId(int i, int i1) {
        return 0;
    }
    //返回一个布尔值,表示适配器的项目是否具有稳定的唯一标识符。如果返回 true,则表示每个项的标识符在数据集的生命周期内保持稳定
    public boolean hasStableIds() {
        return false;
    }
    //获取父项的视图
    public View getGroupView(int i, boolean b, View view, ViewGroup viewGroup) {
        return null;
    }
    //获取子项的视图
    public View getChildView(int i, int i1, boolean b, View view, ViewGroup viewGroup) {
        return null;
    }
    //返回一个布尔值,表示特定的子项是否可选
    public boolean isChildSelectable(int i, int i1) {
        return false;
    }
    //返回一个布尔值,表示所有的列表项是否可选。一般情况下,如果所有项都是可选的,则返回 true
    public boolean areAllItemsEnabled() {
        return false;
    }
    //返回一个布尔值,表示适配器是否为空。
    public boolean isEmpty() {
        return false;
    }
    //在父项展开时被调用
    public void onGroupExpanded(int i) {

    }
    //在父项折叠时被调用
    public void onGroupCollapsed(int i) {

    }
    //用于获取子项的组合ID。这在某些情况下可以用于唯一标识某个项。
    public long getCombinedChildId(long l, long l1) {
        return 0;
    }
    //用于获取父项的组合ID。这在某些情况下可以用于唯一标识某个项。
    public long getCombinedGroupId(long l) {
        return 0;
    }
}

4. 数据观察者的使用

在Android中,要让DataSetObserver(数据观察者)监听数据,通常需要将它注册到适配器(Adapter)或者数据集(DataSet)上。然后,当数据集的内容发生变化时,DataSetObserver中相应的方法会被自动调用。

//获取控件
ExpandableListView expandableListView=findViewById(R.id.expandableListView);

//创建适配器
MyAdapter myAdapter=new MyAdapter();

//创建数据观察者
DataSetObserver dataSetObserver=new DataSetObserver() {
    public void onChanged() {
        super.onChanged();
        //数据变化时修改UI
    }
    public void onInvalidated() {
        super.onInvalidated();
        //数据集无效时调用此方法
    }
};

//注册数据观察者
myAdapter.registerDataSetObserver(dataSetObserver);
//设置适配器
expandableListView.setAdapter(myAdapter);

//...数据变化...
//使用数据观察者,调用onChanged方法
myAdapter.dataSetObserver.onChanged();

5. 案例代码一览

<!--activity_main_xml-->

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">
    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent">
        <ExpandableListView
            android:id="@+id/expandableListView"
            android:layout_width="match_parent"
            android:layout_height="match_parent"/>
    </RelativeLayout>
</androidx.constraintlayout.widget.ConstraintLayout>
<!--group_layout.xml-->

<?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="50dp"
    android:background="@color/teal_200">
    <TextView
        android:id="@+id/group_textView"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerInParent="true"
        android:text="group-null"/>
</RelativeLayout>
<!--child_layout.xml-->

<?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="30dp"
    android:background="@color/purple_700">
    <TextView
        android:id="@+id/child_textView"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="child-null"/>
</RelativeLayout>
//自定义适配器

class MyAdapter implements ExpandableListAdapter {
    ArrayList<View> groupArrayList=null;
    ArrayList<ArrayList<View>> childArrayLists=null;
    public MyAdapter(ArrayList<View> groupArrayList,ArrayList<ArrayList<View>> childArrayLists){
        //构造方法,可以在参数中进行数据传入
        this.groupArrayList=groupArrayList;
        this.childArrayLists=childArrayLists;
    }
    //返回父项的数量,即可展开列表中的组数
    public int getGroupCount() {
        return groupArrayList.size();
    }
    //返回特定组(父项)中子项的数量
    public int getChildrenCount(int i) {
        return childArrayLists.get(i).size();
    }
    //获取父项的视图
    public View getGroupView(int i, boolean b, View view, ViewGroup viewGroup) {
        return groupArrayList.get(i);
    }
    //获取子项的视图
    public View getChildView(int i, int i1, boolean b, View view, ViewGroup viewGroup) {
        return childArrayLists.get(i).get(i1);
    }
    //返回一个布尔值,表示特定的子项是否可选
    public boolean isChildSelectable(int i, int i1) {
        return false;
    }
    
    //...其他方法
}
//MainActivity.java

public class MainActivity extends AppCompatActivity {
    @SuppressLint("MissingInflatedId")
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        //准备参数
        ArrayList<View> groupArrayList=new ArrayList<>();
        ArrayList<ArrayList<View>> childArrayLists=new ArrayList<>();
        for(int i=0;i<10;i++){
            //group
            View view= LayoutInflater.from(MainActivity.this).inflate(R.layout.group_layout,null);
            ((TextView)view.findViewById(R.id.group_textView)).setText("group:"+i);
            groupArrayList.add(view);
            //child
            ArrayList<View> childArrayList=new ArrayList<>();
            for(int i1=0;i1<6;i1++){
                View view1=LayoutInflater.from(MainActivity.this).inflate(R.layout.child_layout,null);
                ((TextView)view1.findViewById(R.id.child_textView)).setText("child:"+i1);
                childArrayList.add(view1);
            }
            childArrayLists.add(childArrayList);
        }

        //获取控件
        ExpandableListView expandableListView=findViewById(R.id.expandableListView);

        //创建适配器
        MyAdapter myAdapter=new MyAdapter(groupArrayList,childArrayLists);
        //设置适配器
        expandableListView.setAdapter(myAdapter);
    }
}

tag:ExpandableListView;可扩展列表视图;可折叠列表视图;适配器;Adapter

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1607284.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

科研基础与工具(笔记)

​ 免责申明&#xff1a; 本文内容只是学习笔记&#xff0c;不代表个人观点&#xff0c;希望各位看官自行甄别 参考文献 科研基础与工具&#xff08;YouTube&#xff09; 专业名词 影响因子&#xff08;Impact Factor&#xff09;&#xff0c;一般是特指SCI的影响因子&#…

Qt实现Mysql数据库的连接,查询,修改,删除,增加功能

Qt实现Mysql数据库的连接&#xff0c;查询&#xff0c;修改&#xff0c;删除&#xff0c;增加功能 安装Mysql数据库&#xff0c;QtCreator Mysql选择Mysql Server 8.1版本安装。 Mysql Server 8.1安装过程 1.首先添加网络服务权限&#xff1a; WinR键输入compmgmt.msc进入…

论文阅读:BEVBert: Multimodal Map Pre-training for Language-guided Navigation

BEVBert&#xff1a;语言引导导航的多模态地图预训练 摘要 现存的问题&#xff1a;目前大多数现有的预训练方法都采用离散的全景图来学习视觉-文本关联。这要求模型隐式关联全景图中不完整、重复的观察结果&#xff0c;这可能会损害智能体的空间理解。 本文解决方案&#xf…

PCBA镀金工艺介绍

PCBA&#xff08;印制电路板组装&#xff09;的镀金工艺是一种常见的表面处理方法&#xff0c;用于提高印制电路板&#xff08;PCB&#xff09;的性能和耐用性。本文将详细介绍PCBA的镀金工艺&#xff0c;包括其类型、工艺流程、优点及应用。 1. 镀金工艺的类型 PCBA的镀金主要…

Mac电脑版鼠标连点工具 RapidClick for Mac

RapidClick for Mac是一款方便实用的自动点击工具&#xff0c;可以帮助Mac用户在使用电脑时轻松、快速地进行鼠标操作。它可以模拟人类手指点击的动作&#xff0c;让您的鼠标点击变得更加快捷高效&#xff0c;大大提升了工作和游戏的效率。 RapidClick for Macv1.5.1激活版下载…

【windows-搭建Ubuntu22LTS】

一、环境要求 1. windows版本要求 至少Windows 10 2020年5月(2004) 版, Windows 10 2019年5月(1903) 版&#xff0c;或者 Windows 10 2019年11月(1909) 版 2. 控制面板开启相关的程序(需要重启) 二、Microsoft store安装unbuntu 下载后直接运行&#xff08;稍微等会&#…

mac: docker安装及其Command not found: docker

已经安装了docker desktop&#xff0c;没安装的 点击安装 傻瓜式安装即可 接着打开终端&#xff1a;好一个 Comand not found:docker 看我不把你整顿&#xff0c;解决如下&#xff1a; 如果你在 macOS 上安装了 Docker Desktop&#xff0c;但是终端无法识别 docker 命令&…

【ARM 裸机】汇编 led 驱动之烧写 bin 文件

1、烧写概念 bin 文件烧写到哪里呢&#xff1f;使用 STM32 的时候烧写到内部 FLASH&#xff0c;6ULL 没有内部 FLASH&#xff0c;是不是就不能烧写呢&#xff1f;不&#xff0c;6ULL 支持 SD卡、EMMC、NAND FLASH、NOR FLASH 等方式启动&#xff0c;在裸机学习的工程中&#x…

C++算法题 - 区间

目录 228. 汇总区间56. 合并区间57. 插入区间452. 用最少数量的箭引爆气球 228. 汇总区间 LeetCode_link 给定一个 无重复元素 的 有序 整数数组 nums 。 返回 恰好覆盖数组中所有数字 的 最小有序 区间范围列表 。也就是说&#xff0c;nums 的每个元素都恰好被某个区间范围所…

IDEA报错然后pycharm闪退

pycharm闪退&#xff0c;在C盘的USER文件夹下有报错文件 打开一看&#xff0c;说内存不足 # There is insufficient memory for the Java Runtime Environment to continue. # Native memory allocation (mmap) failed to map 14596177920 bytes for G1 virtual space # Possib…

Redis入门到通关之分布式锁Rediision

文章目录 ☃️setnx实现的分布式锁存的问题☃️Redisson☃️分布式锁-Redission快速入门☃️实战☃️总结 ☃️setnx实现的分布式锁存的问题 基于setnx实现的分布式锁存在下面的问题&#xff1a; 重入问题&#xff1a;重入问题是指 获得锁的线程可以再次进入到相同的锁的代码…

Win10系统下关闭管理员运行确认弹窗

Windows10及以上系统对于安全的考虑&#xff0c;对于程序运行时的权限做了控制 点击后&#xff0c;会弹出确认的弹窗。 像我做测试&#xff0c;或者使用cmd经常需要administrator 权限&#xff0c;一直弹弹弹就很烦。 要实现右击后无需弹窗就可以使用管理员权限运行改…

世强硬创获Jowat授权代理,其热熔胶可实现重新分离和循环使用

随着全球对环境保护意识的提升&#xff0c;政府机构对挥发性有机化合物&#xff08;VOCs&#xff09;和其他有害排放物的限制越来越严格&#xff0c;这促使粘合剂制造厂商开发更环保的产品。 为拓展中国市场&#xff0c;德国胶王股份有限公司&#xff08;下称“德国胶王”&…

FX110网:香港交易所宣布开发Orion衍生品平台,预计于 2028 年推出

香港交易及结算所有限公司&#xff08;香港交易所&#xff0c;HKEX&#xff09;今天宣布开发 Orion 衍生品平台&#xff08;ODP&#xff09;&#xff0c;提供增强的交易、清算和风险管理能力。 这个新平台由香港交易所技术团队自行开发&#xff0c;预计于 2028 年推出&#xff…

LeetCode题目42:接雨水【python 42/1000】

作者介绍&#xff1a;10年大厂数据\经营分析经验&#xff0c;现任大厂数据部门负责人。 会一些的技术&#xff1a;数据分析、算法、SQL、大数据相关、python 欢迎加入社区&#xff1a;码上找工作 作者专栏每日更新&#xff1a; LeetCode解锁1000题: 打怪升级之旅 python数据分析…

[C++][算法基础]求约数(试除法)

给定 n 个正整数 &#xff0c;对于每个整数 &#xff0c;请你按照从小到大的顺序输出它的所有约数。 输入格式 第一行包含整数 n。 接下来 n 行&#xff0c;每行包含一个整数 。 输出格式 输出共 n 行&#xff0c;其中第 i 行输出第 i 个整数 的所有约数。 数据范围 1≤…

直播预告:拥抱AI-探索AI大模型在邮件反钓鱼检测的应用

随着ChatGPT的问世&#xff0c;生成式AI技术迅速渗透到我们生活的各个角落&#xff0c;以ChatGPT为代表的生成式AI技术&#xff0c;依托其强大的AI模型和海量数据&#xff0c;赢得了广泛的欢迎。 然而&#xff0c;生成式AI的不断演进也带来了新的挑战。大型语言模型&#xff08…

单链表-通讯录

目录 单链表实现 通讯录代码实现 初始化 初始化函数 添加 删除 展示 查找 修改 销毁 代码展示 main.c text.c text.h list.c list.h 和前面的通讯录实现差不多这次就是实现一个以单链表为底层的通讯录 单链表实现 数据结构&#xff1a;单链表-CSDN博客 通讯…

【资源分享】SPSS 26免费下载安装

::: block-1 “时问桫椤”是一个致力于为本科生到研究生教育阶段提供帮助的不太正式的公众号。我们旨在在大家感到困惑、痛苦或面临困难时伸出援手。通过总结广大研究生的经验&#xff0c;帮助大家尽早适应研究生生活&#xff0c;尽快了解科研的本质。祝一切顺利&#xff01;—…

(51单片机)第十一章-串行口应用提高

11.1 方式0应用 在第6章中&#xff0c;已经对51单片机的串行口结构做过详细介绍&#xff0c;并且通过实例讲解了串行口的4种工作方式中方式1的具体用法&#xff0c;本节详细讲述串行口方式0的用法。 串行口方式0被称为同步移位寄存器的输入/输出方式&#xff0c;主要用于扩展并…