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 多层级列表实现
方法一: Element.java : package com.chy.ydy.tools.treeutil; /*** TreeView 元素* */ public class Element {/** 文字内容 */private String contentText;/** 在tree中的层级 */private int level;/** 元素的id */private int id;/** 父元素的id */…...
柔数组的介绍
柔数组简单介绍 这个词你可能没有听过但是他的确是存在的。 1.在c99中结构中的最后⼀个元素允许是未知⼤⼩的数组,这就叫做『柔性数组』成员 2这就代表了它存在与结构体中,很重要的一点是,他只能是结构体的最后的一个成员,这是…...
跳槽多次未成功,问题源自何处?
众所周知,2023年市场很难!看着企业们纷纷裁员,甚至连内推这个后门都走不通!哪怕有面试,都是屡屡碰壁,你想清楚问题出在哪了吗?😭“求职不得,夜不能寐;三更半夜…...
Linux 操作系统 022-串口/U盘/共享文件夹
Linux 操作系统 022-串口/U盘/共享文件夹 本节关键字:Linux、centos、串口、U盘、共享文件夹 本节相关指令:echo、cat、mkdir、mount 1、串口 #(1) 查看串口是否可用,可以对串口发送数据比如: $ echo helloworld >/dev/ttyS…...
java题目9:100匹马驮100担货,大马一匹驮3担,中马一匹驮2担,小马两匹驮1担。计算大中小马的数目(HorsesPackGoods9)
每日小语 正是他的意图损坏了他的悟性。——《充足理由律的四重根》 思考 有点鸡兔同笼的感觉嗷, //100匹马驮100担货,大马一匹驮3担,中马一匹驮2担,小马两匹驮1担。计算大中小马的数目(public class HorsesPackGoo…...
操作系统OS Chapter1
操作系统OS 一、概念和功能1.概念2.功能3.目标 二、特征1.并发2.共享3.虚拟4.异步 三、发展四、运行机制五、中断和异常1.中断的作用2.中断的类型3.中断机制的原理 六、系统调用七、操作系统结构八、操作系统引导九、虚拟机 一、概念和功能 1.概念 操作系统(OS&…...
UE4_Mouse_Interaction——拖拽物体的实现
鼠标拖拽物体,效果如下图: 1、新建PlayerController,更名字为MI_PlayerController,双击打开并设置参数: 2、新建GameMode,更名为MI_Gameinfo。参数如下设置: 3、新建材质,更名为BasicAsset02.参…...
Tomcat配置https
前言:本文内容为实操记录,仅供参考! 一、证书 CA证书申请下载不赘述了。 二、上传证书 进入tomcat根目录,conf同级目录下创建cert文件夹,并将证书两个文件上传到该文件夹; 三、编辑conf/server.xml文件 ① …...
Modelsim手动仿真实例
目录 1. 软件链接 2. 为什么要使用Modelsim 3. Modelsim仿真工程由几部分组成? 4. 上手实例 4.1. 新建文件夹 4.2. 指定目录 4.3. 新建工程 4.4. 新建设计文件(Design Files) 4.5. 新建测试平台文件(Testbench Files&…...
AXI-Stream——草稿版
参考自哔站:FPGA IP之AXI4-Lite AXI4-Stream_哔哩哔哩_bilibili 信号 传输层级从小到大 包(----------transfer--transfer--------)------delay--------包(----------transfer--transfer--------) TKEEP和TSTRB共同决定了是哪种数据流...
【编码器应用】第一节-编码器从从原理到应用详解
概述: 本文内容为常用电机编码器概览,将为您重点介绍编码器大致分类,以及增量编码器与西门子设备的配置连接方式。 编码器简介 编码器是利用LED光源发出的透射光对码盘进行光电扫描,光电元件接收编码器轴旋转时产生的明暗交替变…...
瑞_23种设计模式_中介者模式
文章目录 1 中介者模式(Mediator Pattern)1.1 介绍1.2 概述1.3 中介者模式的结构1.4 中介者模式的优缺点1.5 中介者模式的使用场景 2 案例一2.1 需求2.2 代码实现 3 案例二3.1 需求3.2 代码实现 🙊 前言:本文章为瑞_系列专栏之《2…...
sqlite删除数据表
1.如何删除表 在SQLite中,删除表的SQL语句是DROP TABLE。如果你想要在Python中使用SQLite库(如sqlite3)来删除一个表,你可以按照以下步骤操作: 连接到SQLite数据库。创建一个cursor对象。执行DROP TABLE语句。提交事…...
Spring Boot简介及案例
文章目录 Spring Boot简介以下是一个简单的 Spring Boot Web 应用实例**步骤 1:创建 Spring Boot 项目****步骤 2:编写 RESTful 控制器****步骤 3:配置主类****步骤 4:运行并测试应用** Spring Boot简介 Spring Boot 是一个用于简…...
Learning To Count Everything
提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 摘要Abstract文献阅读:学习数一切东西1、研究背景2、提出方法3、模块详细3.1、多尺度特征提取模块3.2、密度预测模块 4、损失函数5、性能对比6、贡献 二…...
大语言模型(LLM)token解读
1. 什么是token? 人们经常在谈论大模型时候,经常会谈到模型很大,我们也常常会看到一种说法: 参数会让我们了解神经网络的结构有多复杂,而token的大小会让我们知道有多少数据用于训练参数。 什么是token?比…...
【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 | 程序员如何用技术变现?(上)【文章笔记 + 个人思考】
《极客时间 - 左耳听风》 原文链接 :https://time.geekbang.org/column/intro/100002201?tabcatalog 备注:加粗部分为个人思考 程序员用自己的技术变现是天经地义的事情。写程序是一门手艺活,程序员作为手艺人完全可以不依赖任何公司或者其他…...
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 一.服务器概述 服务器硬件:指的也是计算机,只不过服务器要比我们日常使用的计算…...
Golang 面试经典题:map 的 key 可以是什么类型?哪些不可以?
Golang 面试经典题:map 的 key 可以是什么类型?哪些不可以? 在 Golang 的面试中,map 类型的使用是一个常见的考点,其中对 key 类型的合法性 是一道常被提及的基础却很容易被忽视的问题。本文将带你深入理解 Golang 中…...
理解 MCP 工作流:使用 Ollama 和 LangChain 构建本地 MCP 客户端
🌟 什么是 MCP? 模型控制协议 (MCP) 是一种创新的协议,旨在无缝连接 AI 模型与应用程序。 MCP 是一个开源协议,它标准化了我们的 LLM 应用程序连接所需工具和数据源并与之协作的方式。 可以把它想象成你的 AI 模型 和想要使用它…...
大数据零基础学习day1之环境准备和大数据初步理解
学习大数据会使用到多台Linux服务器。 一、环境准备 1、VMware 基于VMware构建Linux虚拟机 是大数据从业者或者IT从业者的必备技能之一也是成本低廉的方案 所以VMware虚拟机方案是必须要学习的。 (1)设置网关 打开VMware虚拟机,点击编辑…...
HTML前端开发:JavaScript 常用事件详解
作为前端开发的核心,JavaScript 事件是用户与网页交互的基础。以下是常见事件的详细说明和用法示例: 1. onclick - 点击事件 当元素被单击时触发(左键点击) button.onclick function() {alert("按钮被点击了!&…...
Caliper 配置文件解析:config.yaml
Caliper 是一个区块链性能基准测试工具,用于评估不同区块链平台的性能。下面我将详细解释你提供的 fisco-bcos.json 文件结构,并说明它与 config.yaml 文件的关系。 fisco-bcos.json 文件解析 这个文件是针对 FISCO-BCOS 区块链网络的 Caliper 配置文件,主要包含以下几个部…...
Spring是如何解决Bean的循环依赖:三级缓存机制
1、什么是 Bean 的循环依赖 在 Spring框架中,Bean 的循环依赖是指多个 Bean 之间互相持有对方引用,形成闭环依赖关系的现象。 多个 Bean 的依赖关系构成环形链路,例如: 双向依赖:Bean A 依赖 Bean B,同时 Bean B 也依赖 Bean A(A↔B)。链条循环: Bean A → Bean…...
Linux离线(zip方式)安装docker
目录 基础信息操作系统信息docker信息 安装实例安装步骤示例 遇到的问题问题1:修改默认工作路径启动失败问题2 找不到对应组 基础信息 操作系统信息 OS版本:CentOS 7 64位 内核版本:3.10.0 相关命令: uname -rcat /etc/os-rele…...
TSN交换机正在重构工业网络,PROFINET和EtherCAT会被取代吗?
在工业自动化持续演进的今天,通信网络的角色正变得愈发关键。 2025年6月6日,为期三天的华南国际工业博览会在深圳国际会展中心(宝安)圆满落幕。作为国内工业通信领域的技术型企业,光路科技(Fiberroad&…...
[USACO23FEB] Bakery S
题目描述 Bessie 开了一家面包店! 在她的面包店里,Bessie 有一个烤箱,可以在 t C t_C tC 的时间内生产一块饼干或在 t M t_M tM 单位时间内生产一块松糕。 ( 1 ≤ t C , t M ≤ 10 9 ) (1 \le t_C,t_M \le 10^9) (1≤tC,tM≤109)。由于空间…...
aardio 自动识别验证码输入
技术尝试 上周在发学习日志时有网友提议“在网页上识别验证码”,于是尝试整合图像识别与网页自动化技术,完成了这套模拟登录流程。核心思路是:截图验证码→OCR识别→自动填充表单→提交并验证结果。 代码在这里 import soImage; import we…...
