20241121 android中树结构列表(使用recyclerView实现)

1、adapter-item的布局

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"android:layout_width="match_parent"android:layout_height="wrap_content"android:id="@+id/item_cl"android:padding="@dimen/dp_10"xmlns:app="http://schemas.android.com/apk/res-auto"><TextViewandroid:id="@+id/item_label"android:layout_width="wrap_content"android:layout_height="match_parent"app:layout_constraintTop_toTopOf="parent"app:layout_constraintStart_toEndOf="@id/item_down_iv"app:layout_constraintBottom_toBottomOf="parent"/><ImageViewandroid:id="@+id/item_down_iv"android:layout_width="@dimen/dp_20"android:layout_height="@dimen/dp_20"android:src="@mipmap/icon_tree_export"android:visibility="visible"app:layout_constraintStart_toStartOf="parent"app:layout_constraintEnd_toStartOf="@id/item_label"app:layout_constraintTop_toTopOf="parent"/></androidx.constraintlayout.widget.ConstraintLayout>

2、adapter的设计代码

使用最简单的方式进行实现树状结构,并对展开和关闭进行处理
1、将树状结构数据整理成list结构
2、初始化展示效果
3、在展开过程中,需要注意的是直接在父项的下方进行数据的添加,而移除的话就是需要递归移除数据

import android.content.Context
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.ImageView
import android.widget.LinearLayout
import android.widget.TextView
import androidx.recyclerview.widget.RecyclerView
import cn.lisi.envirolablims.R
import cn.lisi.envirolablims.client.adapter.TreeItemAdapter.TreeViewHolder
import cn.lisi.envirolablims.client.bean.response.DeptTreeBean
import cn.lisi.envirolablims.client.bean.response.DeptTreeInfo
import cn.lisi.envirolablims.client.util.LogdUtilclass TreeItemAdapter(val mContext: Context) : RecyclerView.Adapter<TreeViewHolder>() {/*** 所有的数据*/private val mDataList: MutableList<DeptTreeBean> = ArrayList()private var mCurrentDataList: MutableList<DeptTreeBean> = ArrayList()override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): TreeViewHolder {return TreeViewHolder(LayoutInflater.from(mContext).inflate(R.layout.rc_item_tree_item_layout, parent, false))}override fun getItemCount(): Int {return mCurrentDataList.size}fun submitDataList(dataList: MutableList<DeptTreeInfo>) {initTreeList(dataList, 0, -1L, false, false)initCurrentTreenList()notifyDataSetChanged()}override fun onBindViewHolder(holder: TreeViewHolder, position: Int) {holder.treeText.text = mCurrentDataList[position].label//根据点击修改效果holder.treeItem.setOnClickListener {mCurrentDataList.forEach { item ->item.isSelect = falseholder.treeItem.setBackgroundResource(R.color.white)}mCurrentDataList[position].isSelect = truenotifyDataSetChanged()mTreeClickInterface.itemClickListener(position,mCurrentDataList[position])}holder.treeText.setTextColor(mContext.getColor(R.color.black))if (mCurrentDataList[position].isSelect) {holder.treeText.setTextColor(mContext.getColor(R.color.blue_green))}//判断层级,显示marginval paramMargin = (holder.treeItem.layoutParams as LinearLayout.LayoutParams)paramMargin.setMargins((50 * (mCurrentDataList[position].level) + 24),0,0,0)holder.treeItem.layoutParams = paramMargin//判断是否有子项if (mCurrentDataList[position].isHasChild) {holder.treeImage.visibility = View.VISIBLEif (mCurrentDataList[position].isExport) {holder.treeImage.setImageResource(R.mipmap.icon_tree_export)} else {holder.treeImage.setImageResource(R.mipmap.icon_tree_import)}holder.treeImage.setOnClickListener {//展开if (mCurrentDataList[position].isExport) {//跨层次移除removeItemList(mCurrentDataList[position].id)mCurrentDataList[position].isExport = false} else {val insetList: MutableList<DeptTreeBean> = ArrayList()mDataList.forEach { item ->if (item.parentId == mCurrentDataList[position].id) {insetList.add(item)LogdUtil.e("initCustomerShownList", "item 增加的数据 $item")//在展开的之后增加,而不是最后增加}}mCurrentDataList = initCustomerShownList (mCurrentDataList, mCurrentDataList[position].id, insetList)mCurrentDataList[position].isExport = true}notifyDataSetChanged()}} else {holder.treeImage.visibility = View.GONE}}private fun removeItemList(parentId: Long) {mDataList.forEach { item ->if (parentId == item.parentId){mCurrentDataList.remove(item)if (item.isHasChild){removeItemList(item.id)}}}}private fun initCustomerShownList(currentDataList:MutableList<DeptTreeBean>,parentId: Long, insetList: MutableList<DeptTreeBean>):MutableList<DeptTreeBean> {var currentIndex = 1000val endList: MutableList<DeptTreeBean> = ArrayList()val startList: MutableList<DeptTreeBean> = ArrayList()currentDataList.forEach { item ->if (item.id == parentId) {currentIndex = currentDataList.indexOf(item)}if (currentDataList.indexOf(item) > currentIndex) {endList.add(item)}else{startList.add(item)}}currentDataList.clear()currentDataList.addAll(startList)currentDataList.addAll(insetList)currentDataList.addAll(endList)return currentDataList}/*** 将树结构整合成列表形式*/private fun initTreeList(dataList: MutableList<DeptTreeInfo>,level: Int,parentId: Long,isExport: Boolean,isSelect: Boolean) {dataList.forEach { info ->mDataList.add(DeptTreeBean(id = info.id,label = info.label,level = level,isHasChild = !info.children.isNullOrEmpty(),parentId = parentId,isExport = isExport,isSelect = isSelect))if (!info.children.isNullOrEmpty()) {initTreeList(info.children, level + 1, info.id, isExport, isSelect)}}}/*** 设置初始展示效果*/private fun initCurrentTreenList() {mCurrentDataList.clear()mDataList.forEach { info ->if (info.level == 0) {//展开mCurrentDataList.add(info)}}}class TreeViewHolder(val itemView: View) : RecyclerView.ViewHolder(itemView) {val treeItem = itemView.findViewById<LinearLayout>(R.id.item_cl)val treeText = itemView.findViewById<TextView>(R.id.item_label)val treeImage = itemView.findViewById<ImageView>(R.id.item_down_iv)}private lateinit var mTreeClickInterface: TreeClickInterfacefun setOnClickListener(clickInterface:TreeClickInterface){mTreeClickInterface = clickInterface}interface TreeClickInterface{fun itemClickListener(position: Int,bean:DeptTreeBean)}
}

3、树状adapter的bean

data class DeptTreeInfo(val children: MutableList<DeptTreeInfo>? = ArrayList(), val id: Long, val label: String)data class DeptTreeBean(val id: Long,val label: String,val level: Int,val isHasChild: Boolean,val parentId: Long,var isExport: Boolean,var isSelect:Boolean
)

4、实现布局

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"xmlns:tools="http://schemas.android.com/tools"android:layout_width="match_parent"android:layout_height="match_parent"app:layout_constraintTop_toTopOf="parent"app:layout_constraintBottom_toBottomOf="parent"xmlns:app="http://schemas.android.com/apk/res-auto"tools:ignore="MissingDefaultResource"><androidx.recyclerview.widget.RecyclerViewandroid:id="@+id/recycler_view"android:layout_width="match_parent"android:layout_height="0dp"android:layout_marginBottom="@dimen/margin_20dp"app:layout_constraintTop_toTopOf="parent"app:layout_constraintBottom_toBottomOf="parent"app:layout_constraintStart_toStartOf="parent"app:layout_constraintEnd_toEndOf="parent"/></androidx.constraintlayout.widget.ConstraintLayout>

5、实现代码


//EquipmentDeptTreeList为所需的树结构数据
val adapter = TreeItemAdapter(this)//  adapter.submitDataList(GloableLocalStore.EquipmentDeptTreeList)adapter.submitDataList(mutableListOf(DeptTreeInfo(mutableListOf(DeptTreeInfo(children = null,id = 1,label = "数字1"),DeptTreeInfo(children = null,id = 2,label = "数字2"),DeptTreeInfo(children = mutableListOf(DeptTreeInfo(children = mutableListOf(DeptTreeInfo(children = null,id = 311,label = "数字311"),DeptTreeInfo(children = null,id = 312,label = "数字312")),id = 31,label = "数字31"),DeptTreeInfo(children = null,id = 32,label = "数字32")),id = 3,label = "数字3"),DeptTreeInfo(children = mutableListOf(DeptTreeInfo(children = mutableListOf(DeptTreeInfo(children = mutableListOf(DeptTreeInfo(children = null,id = 4111,label = "数字4111"),DeptTreeInfo(children = null,id = 4112,label = "数字4112")),id = 411,label = "数字411"),DeptTreeInfo(children = mutableListOf(DeptTreeInfo(children = null,id = 4121,label = "数字4121"),DeptTreeInfo(children = null,id = 4122,label = "数字4122")),id = 412,label = "数字412")),id = 41,label = "数字41"),DeptTreeInfo(children = null,id = 42,label = "数字42")),id = 4,label = "数字4"),DeptTreeInfo(children = mutableListOf(DeptTreeInfo(children = null,id = 51,label = "数字51"),DeptTreeInfo(children = null,id =52,label = "数字52")),id = 5,label = "数字5"),DeptTreeInfo(children = null,id = 6,label = "数字6")), id = 0, label = "数字0")))adapter.setOnClickListener(object : TreeItemAdapter.TreeClickInterface {override fun itemClickListener(position: Int, bean: DeptTreeBean) {LogdUtil.d("lucky","点击获取的数据 position $position \n bean $bean")}})binding.recyclerView.adapter = adapterbinding.recyclerView.layoutManager =LinearLayoutManager(this@EquipmentStateActivity, LinearLayoutManager.VERTICAL, false)

实现效果为:
在这里插入图片描述

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

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

相关文章

C++初阶学习 第十二弹——stack与queue的介绍和使用

目录 一、stack&#xff08;栈&#xff09; 1.栈的概念&#xff1a; 2.成员函数包括&#xff1a; 3.栈的使用示例: 4. 使用时的注意事项&#xff1a; 二.queue&#xff08;队列&#xff09; 1.队列的概念 2.成员函数 3.队列的使用示例 4.使用时的注意事项 三.总结…

如何实现点击目录跳转到指定位置?【vue】

需求&#xff1a;实现目录点击跳转到指定位置&#xff0c;点击后直接定位到指定模块 效果&#xff1a; 实现方法&#xff1a; &#xff08;1&#xff09;a标签跳转 普通使用&#xff1a; <!DOCTYPE html> <html><head><title>a-Demo</title>&l…

【SKFramework框架】二、快速启动

推荐阅读 CSDN主页GitHub开源地址Unity3D插件分享QQ群&#xff1a;398291828小红书小破站 大家好&#xff0c;我是佛系工程师☆恬静的小魔龙☆&#xff0c;不定时更新Unity开发技巧&#xff0c;觉得有用记得一键三连哦。 一、前言 【Unity3D框架】SKFramework框架完全教程《全…

鸿蒙多线程开发——线程间数据通信对象02

1、前 言 本文的讨论是接续鸿蒙多线程开发——线程间数据通信对象01的讨论。在上一篇文章中&#xff0c;我们讨论了常规的JS对象(普通JSON对象、Object、Map、Array等)、ArrayBuffer。其中讨论了ArrayBuffer的复制传输和转移传输方式。 下面&#xff0c;我们将讨论SharedArra…

时序论文22|ICML24港科大:面向多变量不规则的时间序列预测方法

论文标题&#xff1a;Irregular Multivariate Time Series Forecasting: A Transformable Patching Graph Neural Networks Approach 论文链接&#xff1a;https://openreview.net/pdf?idUZlMXUGI6e 前言 这篇文章在“定位研究问题”方面很值得学习。其实前段时间对时序研究…

Linux离线安装Docker命令,简单镜像操作

解压安装包 首先&#xff0c;使用 tar 命令解压 docker-27.3.1.tgz 安装包&#xff1a; tar -zxvf docker-27.3.1.tgz 将二进制文件移动到可执行路径上的目录 接着&#xff0c;将解压出来的 Docker 二进制文件复制到系统的可执行路径&#xff08;通常是 /usr/bin/&#xff09…

Sigrity SPEED2000 TDR TDT Simulation模式如何进行时域阻抗仿真分析操作指导-差分信号

Sigrity SPEED2000 TDR TDT Simulation模式如何进行时域阻抗仿真分析操作指导-差分信号 Sigrity SPEED2000 TDR TDT Simulation模式如何进行时域阻抗仿真分析操作指导-单端信号详细介绍了单端信号如何进行TDR仿真分析,下面介绍如何对差分信号进行TDR分析,还是以下图为例进行分…

springboot基于微信小程序的食堂预约点餐系统

摘 要 基于微信小程序的食堂预约点餐系统是一种服务于学校和企事业单位食堂的智能化解决方案&#xff0c;旨在提高食堂就餐的效率、缓解排队压力&#xff0c;并优化用户的就餐体验。系统作为一种现代化的解决方案&#xff0c;为食堂管理和用户就餐提供了便捷高效的途径。它不仅…

Java线程池详解

线程池是用来管理和复用线程的一种技术&#xff0c;它避免了频繁的创建和销毁线程的开销&#xff0c;提高了应用程序的性能。在 Java 中&#xff0c;ExecutorService 是一个非常常用的接口&#xff0c;它提供了线程池的基本功能。 1. 线程池的优势 线程复用&#xff1a;线程池…

软件测试—— Selenium 常用函数(二)

前一篇文章&#xff1a;软件测试—— Selenium 常用函数&#xff08;一&#xff09;-CSDN博客 目录 前言 一、浏览器 1.常见操作 &#xff08;1&#xff09;打开网站 &#xff08;2&#xff09;前进、后退、刷新 2.参数设置 &#xff08;1&#xff09;设置无头模式 &am…

webgl threejs 云渲染(服务器渲染、后端渲染)解决方案

云渲染和流式传输共享三维模型场景 1、本地无需高端GPU设备即可提供三维项目渲染 云渲染和云流化媒体都可以让3D模型共享变得简单便捷。配备强大GPU的远程服务器早就可以处理密集的处理工作&#xff0c;而专有应用程序&#xff0c;用户也可以从任何个人设备查看全保真模型并与…

springboot基于Spring Boot的古城景区管理系统的设计与实现docx

摘 要 古城景区管理系统是一个集景区导游功能于一体的综合管理平台&#xff0c;旨在提升游客的参观体验和提高管理效率。系统通过提供详尽的热门景点、客房类型、酒店信息、美食类型、特色美食、文创产品及导游服务&#xff0c;使游客能够深入了解古城的历史与文化。该系统集成…

彻底理解如何保证Redis和数据库数据一致性问题

一.背景 系统中缓存最常用的策略是&#xff1a;服务端需要同时维护 DB 和 Cache 并且是以 DB 的结果为准&#xff0c;那么就可能出现 DB 和 Cache 数据不一致的问题。 二.读数据 逻辑如下&#xff1a; 当客户端发起查询数据的请求&#xff0c;首先回去Redis中查看没有没该数据&…

openwebui使用

文章目录 1、feature2、安装使用2.1 安装过程2.2 安装好后 1、feature 可以加载多个大模型 同时回复 模型问答: 使用vLLM框架部署模型&#xff0c;再使用Open WebUI直接进行模型问答 多模型支持: 多模型回复比对&#xff08;Qwen2-72B-Instruct, llama3-70b-8192, mixtral-8x7…

.net 8使用hangfire实现库存同步任务

C# 使用HangFire 第一章:.net Framework 4.6 WebAPI 使用Hangfire 第二章:net 8使用hangfire实现库存同步任务 文章目录 C# 使用HangFire前言项目源码一、项目架构二、项目服务介绍HangFire服务结构解析HangfireCollectionExtensions 类ModelHangfireSettingsHttpAuthInfoUs…

【已解决】“EndNote could not connect to the online sync service”问题的解决

本人不止一次在使用EndNote软件时遇到过“EndNote could not connect to the online sync service”这个问题。 过去遇到这个问题都是用这个方法来解决&#xff1a; 这个方法虽然能解决&#xff0c;但工程量太大&#xff0c;每次做完得歇半天身体才能缓过来。 后来再遇到该问…

私有化部署视频平台EasyCVR宇视设备视频平台如何构建视频联网平台及升级视频转码业务?

在当今数字化、网络化的时代背景下&#xff0c;视频监控技术已广泛应用于各行各业&#xff0c;成为保障安全、提升效率的重要工具。然而&#xff0c;面对复杂多变的监控需求和跨区域、网络化的管理挑战&#xff0c;传统的视频监控解决方案往往显得力不从心。 EasyCVR视频融合云…

Ubuntu从入门到精通(二)远程和镜像源配置齐全

Ubuntu从入门到精通(二) 1 常见操作配置 1.1 英文语言配置 1.1.1 打开设置 1.1.2 设置语言为英文 1.1.3 重启生效 1.1.4 再次进入,选择更新名字 1.1.5 再次进入,发现已经变成了英文 1.2 输入法配置 1.3 rustdesk安装 1.3.1 Windows系统配置 登陆:https://github.com…

【Node.js】全面解析 Node.js 安全最佳实践:保护您的应用

Node.js 是一种强大的 JavaScript 运行时&#xff0c;广泛用于构建现代 Web 应用和 API。然而&#xff0c;由于其开放性和异步特性&#xff0c;Node.js 应用容易受到多种安全威胁的攻击&#xff0c;比如 SQL 注入、跨站脚本 (XSS) 和拒绝服务攻击 (DoS)。在本文中&#xff0c;我…

Spring Cloud Alibaba、Spring Cloud 与 Spring Boot各版本的对应关系

参考spring-cloud-alibaba github wiki说明&#xff1a;版本说明 下面截取说明&#xff1a; 2022.x 分支 2021.x 分支 2.2.x 分支 组件版本关系