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

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.mrgr.cn/news/77670.html

相关文章:

  • Vscode写markdown快速插入python代码
  • 【尚筹网】二、环境搭建一
  • pytest日志总结
  • 动态规划 —— 子数组系列-环绕字符串中唯⼀的子字符串
  • 前端三剑客(三):JavaScript
  • 计算机毕设-基于springboot的复兴村医疗管理系统的设计与实现(附源码+lw+ppt+开题报告)
  • 设计模式:4、命令模式(双重委托)
  • Altium Designer学习笔记 11-15 原理图的封装 编译 检查 _PCB封装库的创建
  • Android Studio 设置不显示 build-tool 无法下载
  • 各种语言书籍下载
  • leetcode-44-通配符匹配
  • 【web前端笔记】vue3 + vite的前端项目中,使用import.meta.glob()方法实现全局注册组件的通用代码
  • Linux从入门到精通
  • wsl使用
  • Node.js
  • Spring:IOC实例化对象bean的方式
  • 第二十二章 TCP 客户端 服务器通信 - TCP设备的OPEN和USE命令关键字
  • 【算法速刷(10/100)】LeetCode —— 23. 合并 K 个升序链表
  • Linux---shell脚本
  • Spring Batch :高效处理海量数据的利器
  • 15分钟学 Go 第 56 天:架构设计基本原则
  • 【操作系统不挂科】<Linux进程概念>选择题(带答案与解析)
  • shell数组
  • 预处理(1)(手绘)
  • 低代码平台:跨数据库处理的重要性与实现方式
  • JavaScript 变量:理解基元和引用类型