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,elementsData.get(position));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);}}

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

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

相关文章

动态链接dlopen/dlclose/..

dlopen&#xff0c;dlsym,dlclose可以在不去link shared library的前提下&#xff0c;在runtime时调用shared library里面的函数.这样可以实现shared library的覆盖或是省略编译阶段的链接检查.但dlopen/dlclose要谨慎使用,尤其是有些写的不是很好的shared library. 动态链接函…

搜索与图论——Prim算法求最小生成树

在最小生成树问题里&#xff0c;正边和负边都没问题 朴素版prim算法 时间复杂度O(n^2) 生成树&#xff1a;每一次选中的t点&#xff0c;它和集合的距离对应的那条边&#xff0c;就是生成树的一条边 算法流程和dijkstra算法非常相似 #include<iostream> #include<cs…

OKCC的API资源管理平台怎么用?

API资源管理平台&#xff0c;重点是“资源”管理平台&#xff0c;不是API接口管理平台。 天天讯通推出的API资源管理平台&#xff0c;类似昆石的VOS系统&#xff0c;区别是VOS是SIP资源管理系统&#xff0c;我们的API资源管理平台是API资源管理系统&#xff08;AXB、AX、回拨AP…

【御控物联】JavaScript JSON结构转换(7):数组To数组——键值互换属性重组

文章目录 一、JSON结构转换是什么&#xff1f;二、案例之《JSON数组 To JSON数组》三、代码实现四、在线转换工具五、技术资料 一、JSON结构转换是什么&#xff1f; JSON结构转换指的是将一个JSON对象或JSON数组按照一定规则进行重组、筛选、映射或转换&#xff0c;生成新的JS…

【Spring Cache】基于注解的缓存框架 简化redis代码

文章目录 一、介绍二、常用注解三、快速入门3.1 EnableCaching3.2 CachePut3.3 Cacheable3.4 CacheEvict 一、介绍 Spring Cache 是一个框架&#xff0c;实现了基于注解的缓存功能&#xff0c;只需要简单地加一个注解&#xff0c;就能实现缓存功能。 Spring Cache 提供了一层…

带你认识线程

线程的概念 前言&#xff1a; 一个程序运行起来&#xff0c;就会对应一个进程&#xff0c;例如&#xff0c;启动一个 Java 程序&#xff0c;就会创建一个 Java 进程。进程也被称为系统分配资源的基本单位。 一个进程可以包含一个线程&#xff0c;也可以包含多个线程&#xff…

政安晨:【Keras机器学习实践要点】(九)—— 保存、序列化和导出模型

目录 介绍 如何保存和加载模型 保存一个Keras模型 装回模型 设置 保存 例子&#xff1a; 自定义对象 向 load_model() 传递自定义对象 使用自定义对象范围 模型序列化 APIs 内存模型克隆 任意对象序列化和反序列化 保存模型权重 内存中的权重传递接口 无状态层…

MYSQL中update的low_priority

low_priority&#xff0c;低优先级 UPDATE [LOW_PRIORITY] tbl_name SET col_name1expr1,col_name2expr2,... mysql中update用low_priority让update不锁定表 MySQL允许你改变语句调度的优先级&#xff0c;它可以使来自多个客户端的查询更好地协作&#xff0c;这样单个客户端就…

蓝桥杯算法基础(32):素数,埃式筛法,快速幂,斐波那契与矩阵幂运算

素数 有些人认为一个人一生中有三个周期&#xff0c;从他或她出生的那一天开始。 这三个周期是身体周期&#xff0c;情感周期的和智力的周期&#xff0c;他们有周期的长度为23&#xff0c;28&#xff0c; 和33天。每一个周期都有一个高峰。在一个周期的高峰期&#xff0c; 一个…

新能源充电桩站场视频汇聚系统建设方案及技术特点分析

随着新能源汽车的普及&#xff0c;充电桩作为新能源汽车的基础设施&#xff0c;其安全性和可靠性越来越受到人们的关注。为了更好地保障充电桩的安全运行与站场管理&#xff0c;TSINGSEE青犀&触角云推出了一套新能源汽车充电桩视频汇聚管理与视频监控方案。 方案采用高清摄…

Springboot之RESTful风格

概述 Restful风格与传统的有一些不同&#xff0c;传统的资源请求中只有Get以及Post两种方式来传递参数&#xff0c;而Restful风格将资源请求按照CRUD增删改查这基本的数据操作分成了四个基本传递方式。其中&#xff0c;Put 和Delete是从Post中分离出来的&#xff0c;可以浅显的…

2024年03月CCF-GESP编程能力等级认证C++编程七级真题解析

本文收录于专栏《C++等级认证CCF-GESP真题解析》,专栏总目录:点这里。订阅后可阅读专栏内所有文章。 一、单选题(每题 2 分,共 30 分) 第 1 题 下列关于排序的说法,正确的是( )。 A. 冒泡排序是最快的排序算法之一。 B. 快速排序通常是不稳定的。 C. 最差情况,N 个元素…

甲骨文护城河(MOAT)分析工具-用户指南

甲骨文护城河&#xff08;MOAT&#xff09;分析工具-用户指南 登录后&#xff0c;您可以通过显示的基于web的用户界面访问Moat Analytics Dashboard。 以下是如何通过UI使用护城河的指南的使用目录&#xff1a; 一、主屏幕导航 在面板中创建警报和导出 二、无效流量概述 什…

深入浅出MHA(MySQL Master High Availability)集群:原理、部署与实践

目录 引言 一、MHA集群介绍 &#xff08;一&#xff09;什么是MHA &#xff08;二&#xff09;MHA集群原理 &#xff08;三&#xff09;同步方式 &#xff08;四&#xff09;管理节点与数据节点 二、实现MHA &#xff08;一&#xff09;搭建主从复制环境 1.搭建时间同…

Github profile Readme实现小游戏[github自述游戏]

Github profile Readme常用于个人主页介绍&#xff0c;将它与action自动化流程结合&#xff0c;可以实现一些小游戏 例如&#xff1a;2048、五子棋 2048实现 losehu (RUBO) GitHub 五子棋 https://github.com/losehu/losehu/tree/main 通过python/C编写可执行文件&#xf…

【React】React响应事件

在React中&#xff0c;事件处理是组件与用户交互的关键部分。下面我将详细解释你提到的几个点。 1. 编写事件处理函数的不同方法 在React中&#xff0c;事件处理函数通常有以下几种编写方式&#xff1a; a. 箭头函数 在组件的render方法中直接定义箭头函数&#xff1a; class…

Python装饰器与生成器:从原理到实践

一、引言 Python 是一种功能强大且易于学习的编程语言&#xff0c;其丰富的特性使得开发者能够高效地完成各种任务。在 Python 中&#xff0c;装饰器和生成器是两个非常重要的概念&#xff0c;它们能够极大地增强代码的可读性和可维护性。本文将详细介绍如何学习 Python 装饰器…

智能网关BL102E采集西门子PLC S7-200 Smart数据上传至Thingsboard

1、WAN口采集西门子PLC的配置 WAN口可以添加很多设备,具体我们用西门子为例来简要配置。 双击WAN,弹出以太网设置,直接把自动获取IP打开,他会根据你的网段自动设置链接! (1)点击`WAN",点击鼠标右键,点击“添加",弹出设备配置框。 (2)设备名称任意填写,如…

《数据结构学习笔记---第七篇》---栈和队列的OJ练习

1. 括号匹配问题。OJ链接 step1:思路分析 &#xff1a; 1.括号匹配&#xff0c;我们首先考虑用栈实现&#xff0c;我们通过符号栈帧的思想知道&#xff0c;求前中后缀表达式的时候用的就是栈帧&#xff0c;操作数栈和符号栈。 2.根据常见的情况 考虑怎么使用栈&#xff0c;首先…

Bun安装与使用

Bun安装与使用。 它目前无法在windows上直接安装使用&#xff0c;必须通过虚拟机安装。 在win10虚拟机中安装 # 查看内核版本 $ uname -srm Linux 6.1.0-10-amd64 x86_64# 安装unzip解压工具 $ sudo apt install unzip# 下载安装脚本并开始安装 curl -fsSL https://bun.sh/ins…