当前位置: 首页 > news >正文

Android 多层级列表实现

方法一:

Element.java :

package com.chy.ydy.tools.treeutil;
/*** TreeView 元素* */
public class Element {/** 文字内容 */private String contentText;/** 在tree中的层级 */private int level;/** 元素的id */private int id;/** 父元素的id */private int parendId;/** 是否有子元素 */private boolean hasChildren;/** item是否展开 */private boolean isExpanded;/** 表示该节点没有父元素,也就是level为0的节点 */public static final int NO_PARENT = -1;/** 表示该元素位于最顶层的层级 */public static final int TOP_LEVEL = 0;/** 构造函数 */public Element(String contentText, int level, int id, int parendId, boolean hasChildren, boolean isExpanded){super();this.contentText = contentText;this.level = level;this.id = id;this.parendId = parendId;this.hasChildren = hasChildren;this.isExpanded = isExpanded;}public String getContentText() {return contentText;}public void setContentText(String contentText) {this.contentText = contentText;}public int getLevel() {return level;}public void setLevel(int level) {this.level = level;}public int getId() {return id;}public void setId(int id) {this.id = id;}public int getParendId() {return parendId;}public void setParendId(int parendId) {this.parendId = parendId;}public boolean isHasChildren() {return hasChildren;}public void setHasChildren(boolean hasChildren) {this.hasChildren = hasChildren;}public boolean isExpanded() {return isExpanded;}public void setExpanded(boolean expanded) {isExpanded = expanded;}
}
TreeViewAdapter.java:
package com.chy.ydy.tools.treeutil;import android.app.Activity;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ImageView;
import android.widget.TextView;
import com.chy.ydy.R;import java.util.ArrayList;
/*** TreeView 适配器* */
public class TreeViewAdapter extends BaseAdapter {/** 元素数据源 */private ArrayList<Element> elementsData;/** 树中元素 */private ArrayList<Element> elements;/** LayoutInflater */private Activity activity;/** item的行首缩进基数 */private int indentionBase;/** 构造函数 */public TreeViewAdapter(ArrayList<Element> elements, ArrayList<Element> elementsData, Activity activity) {this.elements = elements;this.elementsData = elementsData;this.activity = activity;indentionBase = 50;}/** 树中元素列表 */public ArrayList<Element> getElements() {return elements;}/** 元素数据源列表 */public ArrayList<Element> getElementsData() {return elementsData;}@Overridepublic int getCount() {return elements.size();}@Overridepublic Object getItem(int position) {return elements.get(position);}@Overridepublic long getItemId(int position) {return position;}@Overridepublic View getView(int position, View contentView, ViewGroup parent) {ViewHodler hodler = null;if (contentView == null){hodler = new ViewHodler();LayoutInflater inflater = LayoutInflater.from(activity);// 布局contentView = inflater.inflate(R.layout.treeview_item,null);hodler.prefixImg = contentView.findViewById(R.id.prefixImg);hodler.contentText = contentView.findViewById(R.id.contentText);contentView.setTag(hodler);}else {hodler = (ViewHodler) contentView.getTag();}Element element =elements.get(position); // 获取数据int level = element.getLevel();// 获取该数据层级// 设置前缀图片位置hodler.prefixImg.setPadding(indentionBase * (level+1),hodler.prefixImg.getPaddingTop(),hodler.prefixImg.getPaddingRight(),hodler.prefixImg.getPaddingBottom());// 设置内容hodler.contentText.setText(element.getContentText());// 判断是否有子集并且是否展开if (element.isHasChildren() && !element.isExpanded()){// 设置关闭item前缀图片// 设置图片为关闭hodler.prefixImg.setImageResource(R.mipmap.ic_cancle);//这里要主动设置一下icon可见,因为convertView有可能是重用了"设置了不可见"的view。hodler.prefixImg.setVisibility(View.VISIBLE);} else if (element.isHasChildren() && element.isExpanded()) {// 设置展开item前缀图片// 设置图片为打开hodler.prefixImg.setImageResource(R.mipmap.ic_down);//这里要主动设置一下icon可见,因为convertView有可能是重用了"设置了不可见"的view。hodler.prefixImg.setVisibility(View.VISIBLE);} else if (!element.isHasChildren()) {// 设置没有子集的item前缀图片// 设置图片为打开hodler.prefixImg.setImageResource(R.mipmap.ic_cltd);// 设置了不可见的view。//hodler.prefixImg.setVisibility(View.VISIBLE);// 设置了可见的view。hodler.prefixImg.setVisibility(View.VISIBLE);}return contentView;}/*** 优化Holder* */static class ViewHodler{private ImageView prefixImg;// 前缀图片private TextView contentText;// 内容//private ImageView suffixImg;// 后缀图片}}
TreeViewItemClickListener.java:
package com.chy.ydy.tools.treeutil;import android.view.View;
import android.widget.AdapterView;
import java.util.ArrayList;/*** TreeView item 点击事件* */
public class TreeViewItemClickListener implements AdapterView.OnItemClickListener {/** 没有子集item点击接口 */protected TreeViewNoHasChildrenItemClick noHasChildrenItemClick;/** adapter */private TreeViewAdapter treeViewAdapter;/** 构造函数 */public TreeViewItemClickListener(TreeViewAdapter treeViewAdapter){this.treeViewAdapter = treeViewAdapter;}@Overridepublic void onItemClick(AdapterView<?> parent, View view, int position, long id) {//点击的item代表的元素Element element = (Element) treeViewAdapter.getItem(position);//树中的元素ArrayList<Element> elements = treeViewAdapter.getElements();//元素的数据源ArrayList<Element> elementsData = treeViewAdapter.getElementsData();/** 点击没有子项的item */if (!element.isHasChildren()){// 设置没有子集item点击接口参数noHasChildrenItemClick.onTreeItemClick(position,element);return;}/** 点击有子项的item */if (element.isExpanded()){// 收缩element.setExpanded(false);// 删除节点内部对应子节点数据,包括子节点的字节点...ArrayList<Element> elementsToDel = new ArrayList<Element>();for (int i = position+1;i < elements.size(); i++){if (element.getLevel() >= elements.get(i).getLevel())break;elementsToDel.add(elements.get(i));}elements.removeAll(elementsToDel);treeViewAdapter.notifyDataSetChanged();}else {// 展开element.setExpanded(true);//从数据源中提取子节点数据添加进树,注意这里只是添加了下一级子节点,为了简化逻辑int i = 1;//注意这里的计数器放在for外面才能保证计数有效for (Element e : elementsData){if (e.getParendId() == element.getId()){e.setExpanded(false);elements.add(position+i,e);i++;}}treeViewAdapter.notifyDataSetChanged();}}/*** 设置点击事件* */public void setNoHasChildrenItemClick(TreeViewNoHasChildrenItemClick noHasChildrenItemClick) {this.noHasChildrenItemClick = noHasChildrenItemClick;}/*** 没有子类item点击事件接口* */public interface TreeViewNoHasChildrenItemClick {void onTreeItemClick(int position, Element element);}}

实现代码:

package com.example.javademo;import androidx.appcompat.app.AppCompatActivity;import android.content.Context;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.widget.ListView;
import com.example.javademo.tree.Element;
import com.example.javademo.tree.TreeViewAdapter;
import com.example.javademo.tree.TreeViewItemClickListener;import java.util.ArrayList;public class MainActivity extends AppCompatActivity {/** 树中的元素集合 */private ArrayList<Element> elements;/** 数据源元素集合 */private ArrayList<Element> elementsData;private ListView treeView;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);LayoutInflater inflater = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);init();treeView = findViewById(R.id.treeView);TreeViewAdapter treeViewAdapter = new TreeViewAdapter(elements,elementsData,inflater);TreeViewItemClickListener treeViewItemClickListener = new TreeViewItemClickListener(treeViewAdapter);// 回调函数-没有子集item点击事件treeViewItemClickListener.setNoHasChildrenItemClick(new TreeViewItemClickListener.TreeViewNoHasChildrenItemClick() {@Overridepublic void onTreeItemClick(int position, Element element) {System.out.println("element"+element.getContentText());}});treeView.setAdapter(treeViewAdapter);treeView.setOnItemClickListener(treeViewItemClickListener);}private void init(){elements = new ArrayList<Element>();elementsData = new ArrayList<Element>();//添加节点 -- 节点名称,节点level,节点id,父节点id,是否有子节点,是否展开//添加最外层节点Element n1 = new Element("朝阳区", Element.TOP_LEVEL, 0, Element.NO_PARENT, true, false);// 添加第一层节点Element n11 = new Element("地铁2号线建设广场站", Element.TOP_LEVEL+1,11,n1.getId(),true,false);// 添加第一层节点Element n12 = new Element("地铁5号线湖西路站", Element.TOP_LEVEL+1,12,n1.getId(),true,false);// 添加第一层节点Element n13 = new Element("宽平大路北旧城改造地块", Element.TOP_LEVEL+1,13,n1.getId(),true,false);//添加最外层节点Element n2 = new Element("绿园区", Element.TOP_LEVEL, 1, Element.NO_PARENT, true, false);// 添加第一层节点Element n22 = new Element("合心镇加油站", Element.TOP_LEVEL+1,22,n2.getId(),true,false);// 添加第一层节点Element n23 = new Element("皓月5号地", Element.TOP_LEVEL+1,23,n2.getId(),true,false);// 添加第一层节点Element n24 = new Element("西安桥", Element.TOP_LEVEL+1,24,n2.getId(),true,false);//添加初始树元素elements.add(n1);elements.add(n2);// 创建数据源elementsData.add(n11);elementsData.add(n12);elementsData.add(n13);elementsData.add(n22);elementsData.add(n23);elementsData.add(n24);}}

相关文章:

Android 多层级列表实现

方法一&#xff1a; Element.java &#xff1a; package com.chy.ydy.tools.treeutil; /*** TreeView 元素* */ public class Element {/** 文字内容 */private String contentText;/** 在tree中的层级 */private int level;/** 元素的id */private int id;/** 父元素的id */…...

柔数组的介绍

柔数组简单介绍 这个词你可能没有听过但是他的确是存在的。 1.在c99中结构中的最后⼀个元素允许是未知⼤⼩的数组&#xff0c;这就叫做『柔性数组』成员 2这就代表了它存在与结构体中&#xff0c;很重要的一点是&#xff0c;他只能是结构体的最后的一个成员&#xff0c;这是…...

跳槽多次未成功,问题源自何处?

众所周知&#xff0c;2023年市场很难&#xff01;看着企业们纷纷裁员&#xff0c;甚至连内推这个后门都走不通&#xff01;哪怕有面试&#xff0c;都是屡屡碰壁&#xff0c;你想清楚问题出在哪了吗&#xff1f;&#x1f62d;“求职不得&#xff0c;夜不能寐&#xff1b;三更半夜…...

Linux 操作系统 022-串口/U盘/共享文件夹

Linux 操作系统 022-串口/U盘/共享文件夹 本节关键字&#xff1a;Linux、centos、串口、U盘、共享文件夹 本节相关指令&#xff1a;echo、cat、mkdir、mount 1、串口 #(1) 查看串口是否可用&#xff0c;可以对串口发送数据比如&#xff1a; $ echo helloworld >/dev/ttyS…...

java题目9:100匹马驮100担货,大马一匹驮3担,中马一匹驮2担,小马两匹驮1担。计算大中小马的数目(HorsesPackGoods9)

每日小语 正是他的意图损坏了他的悟性。——《充足理由律的四重根》 思考 有点鸡兔同笼的感觉嗷&#xff0c; //100匹马驮100担货&#xff0c;大马一匹驮3担&#xff0c;中马一匹驮2担&#xff0c;小马两匹驮1担。计算大中小马的数目&#xff08;public class HorsesPackGoo…...

操作系统OS Chapter1

操作系统OS 一、概念和功能1.概念2.功能3.目标 二、特征1.并发2.共享3.虚拟4.异步 三、发展四、运行机制五、中断和异常1.中断的作用2.中断的类型3.中断机制的原理 六、系统调用七、操作系统结构八、操作系统引导九、虚拟机 一、概念和功能 1.概念 操作系统&#xff08;OS&…...

UE4_Mouse_Interaction——拖拽物体的实现

鼠标拖拽物体&#xff0c;效果如下图&#xff1a; 1、新建PlayerController,更名字为MI_PlayerController&#xff0c;双击打开并设置参数&#xff1a; 2、新建GameMode&#xff0c;更名为MI_Gameinfo。参数如下设置&#xff1a; 3、新建材质&#xff0c;更名为BasicAsset02.参…...

Tomcat配置https

前言&#xff1a;本文内容为实操记录&#xff0c;仅供参考&#xff01; 一、证书 CA证书申请下载不赘述了。 二、上传证书 进入tomcat根目录&#xff0c;conf同级目录下创建cert文件夹&#xff0c;并将证书两个文件上传到该文件夹&#xff1b; 三、编辑conf/server.xml文件 ① …...

Modelsim手动仿真实例

目录 1. 软件链接 2. 为什么要使用Modelsim 3. Modelsim仿真工程由几部分组成&#xff1f; 4. 上手实例 4.1. 新建文件夹 4.2. 指定目录 4.3. 新建工程 4.4. 新建设计文件&#xff08;Design Files&#xff09; 4.5. 新建测试平台文件&#xff08;Testbench Files&…...

AXI-Stream——草稿版

参考自哔站&#xff1a;FPGA IP之AXI4-Lite AXI4-Stream_哔哩哔哩_bilibili 信号 传输层级从小到大 包(----------transfer--transfer--------)------delay--------包(----------transfer--transfer--------) TKEEP和TSTRB共同决定了是哪种数据流...

【编码器应用】第一节-编码器从从原理到应用详解

概述&#xff1a; 本文内容为常用电机编码器概览&#xff0c;将为您重点介绍编码器大致分类&#xff0c;以及增量编码器与西门子设备的配置连接方式。 编码器简介 编码器是利用LED光源发出的透射光对码盘进行光电扫描&#xff0c;光电元件接收编码器轴旋转时产生的明暗交替变…...

瑞_23种设计模式_中介者模式

文章目录 1 中介者模式&#xff08;Mediator Pattern&#xff09;1.1 介绍1.2 概述1.3 中介者模式的结构1.4 中介者模式的优缺点1.5 中介者模式的使用场景 2 案例一2.1 需求2.2 代码实现 3 案例二3.1 需求3.2 代码实现 &#x1f64a; 前言&#xff1a;本文章为瑞_系列专栏之《2…...

sqlite删除数据表

1.如何删除表 在SQLite中&#xff0c;删除表的SQL语句是DROP TABLE。如果你想要在Python中使用SQLite库&#xff08;如sqlite3&#xff09;来删除一个表&#xff0c;你可以按照以下步骤操作&#xff1a; 连接到SQLite数据库。创建一个cursor对象。执行DROP TABLE语句。提交事…...

Spring Boot简介及案例

文章目录 Spring Boot简介以下是一个简单的 Spring Boot Web 应用实例**步骤 1&#xff1a;创建 Spring Boot 项目****步骤 2&#xff1a;编写 RESTful 控制器****步骤 3&#xff1a;配置主类****步骤 4&#xff1a;运行并测试应用** Spring Boot简介 Spring Boot 是一个用于简…...

Learning To Count Everything

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 摘要Abstract文献阅读&#xff1a;学习数一切东西1、研究背景2、提出方法3、模块详细3.1、多尺度特征提取模块3.2、密度预测模块 4、损失函数5、性能对比6、贡献 二…...

大语言模型(LLM)token解读

1. 什么是token&#xff1f; 人们经常在谈论大模型时候&#xff0c;经常会谈到模型很大&#xff0c;我们也常常会看到一种说法&#xff1a; 参数会让我们了解神经网络的结构有多复杂&#xff0c;而token的大小会让我们知道有多少数据用于训练参数。 什么是token&#xff1f;比…...

【Micro 2014】NoC Architectures for Silicon Interposer Systems

NoC Architectures for Silicon Interposer Systems 背景和动机 硅中介层 主要内容 基于interposer的多核 NOC架构 试验评估 方法 NoC Architectures for Silicon Interposer Systems Natalie Enright Jerger, University of Toronto Gabriel H. Loh AMD Research 硅中介层…...

《极客时间 - 左耳听风》01 | 程序员如何用技术变现?(上)【文章笔记 + 个人思考】

《极客时间 - 左耳听风》 原文链接 &#xff1a;https://time.geekbang.org/column/intro/100002201?tabcatalog 备注&#xff1a;加粗部分为个人思考 程序员用自己的技术变现是天经地义的事情。写程序是一门手艺活&#xff0c;程序员作为手艺人完全可以不依赖任何公司或者其他…...

Typora结合PicGo + Github搭建个人图床

目录 一 、GitHub仓库设置 1、新建仓库 2、创建Token 并复制保存 二、PicGo客户端配置 1、下载 & 安装 2、配置图床 三、Typora配置 一 、GitHub仓库设置 1、新建仓库 点击主页右上角的 号创建 New repository 填写仓库信息 2、创建Token 并复制保存 点击右上角…...

【JavaWeb】Day27.Web入门——Tomcat介绍

目录 WEB服务器-Tomcat 一.服务器概述 二.Web服务器 三.Tomcat- 基本使用 1.下载 2.安装与卸载 3.启动与关闭 4.常见问题 四.Tomcat- 入门程序 WEB服务器-Tomcat 一.服务器概述 服务器硬件&#xff1a;指的也是计算机&#xff0c;只不过服务器要比我们日常使用的计算…...

AgentCPM深度研报助手C语言文件操作实战:批量处理本地研报文本文件

AgentCPM深度研报助手C语言文件操作实战&#xff1a;批量处理本地研报文本文件 你是不是也遇到过这样的场景&#xff1f;手头有一堆下载好的行业研报&#xff0c;有PDF&#xff0c;有TXT&#xff0c;堆在文件夹里。想快速了解每份报告的核心观点&#xff0c;但一份份打开看&am…...

解锁音乐格式终极指南:一键解决加密音频播放难题

解锁音乐格式终极指南&#xff1a;一键解决加密音频播放难题 【免费下载链接】unlock-music 在浏览器中解锁加密的音乐文件。原仓库&#xff1a; 1. https://github.com/unlock-music/unlock-music &#xff1b;2. https://git.unlock-music.dev/um/web 项目地址: https://gi…...

LangGraph实战:从零构建并部署一个多功能智能体

1. LangGraph框架概述&#xff1a;新一代智能体开发范式 在人工智能应用开发领域&#xff0c;智能体&#xff08;Agent&#xff09;技术正经历着从简单问答到复杂任务执行的进化。LangGraph作为LangChain生态中的新一代开发框架&#xff0c;彻底改变了传统链式结构的局限性。我…...

douyin-downloader:让每个人都能轻松获取无水印视频的技术利器

douyin-downloader&#xff1a;让每个人都能轻松获取无水印视频的技术利器 【免费下载链接】douyin-downloader 项目地址: https://gitcode.com/GitHub_Trending/do/douyin-downloader 一、问题破局&#xff1a;揭开抖音内容获取的神秘面纱 1.1 内容获取的三大拦路虎 …...

客服服务时长难统计?RPA自动记时长,排班更合理

RPA在客服服务时长统计中的应用客服服务时长的准确统计是优化排班和提高效率的关键。传统手动统计方式存在误差大、效率低等问题。RPA&#xff08;机器人流程自动化&#xff09;技术可以自动记录客服工作时长&#xff0c;为排班提供数据支持。RPA自动记录客服工作时长的实现方式…...

数据清洗避坑指南:缺失值和异常值处理的5个常见错误(附真实案例)

数据清洗避坑指南&#xff1a;缺失值和异常值处理的5个常见错误&#xff08;附真实案例&#xff09; 在电商平台的用户行为分析中&#xff0c;我们曾遇到一个诡异现象&#xff1a;某促销活动页面的转化率突然飙升到98%。进一步排查发现&#xff0c;是爬虫程序将未加载完成的页…...

Mac 版 SSH 登录脚本

Mac 版 SSH 登录脚本 整合原有编码机器人 + 新增飞书运营机器人,分区域展示、带完整名称/备注/专线IP,一键登录,Mac 专属、直接可用! 前置准备(仅执行1次) brew install sshpass完整脚本(复制保存为 robot_ssh.sh) #!/bin/bash # Mac 专用 - 编码机器人 + 飞书机器…...

【JavaWeb开发】从零构建前后端交互实战指南

1. JavaWeb前后端交互基础入门 第一次接触JavaWeb开发时&#xff0c;最让我困惑的就是前后端如何传递数据。记得刚开始做项目时&#xff0c;我傻乎乎地用字符串拼接HTML代码返回给前端&#xff0c;结果遇到中文乱码问题折腾了一整天。后来才发现&#xff0c;现代JavaWeb开发早已…...

OpCore-Simplify:智能配置驱动的OpenCore EFI自动化构建工具

OpCore-Simplify&#xff1a;智能配置驱动的OpenCore EFI自动化构建工具 【免费下载链接】OpCore-Simplify A tool designed to simplify the creation of OpenCore EFI 项目地址: https://gitcode.com/GitHub_Trending/op/OpCore-Simplify &#x1f914; 配置黑苹果的痛…...

手把手教你解决Ubuntu22.04中CH341驱动签名问题(附完整安装流程)

手把手教你解决Ubuntu22.04中CH341驱动签名问题&#xff08;附完整安装流程&#xff09; 当你尝试在Ubuntu22.04上使用CH341串口设备时&#xff0c;可能会遇到一个令人头疼的问题——驱动签名验证失败。这个错误不仅会阻止驱动正常加载&#xff0c;还会让许多Linux新手感到束手…...