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

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">
    <TextView
        android: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"
        />
    <ImageView
        android: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.LogdUtil

class 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 = false
                holder.treeItem.setBackgroundResource(R.color.white)
            }
            mCurrentDataList[position].isSelect = true
            notifyDataSetChanged()
            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))
        }

        //判断层级,显示margin
        val 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.VISIBLE
            if (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 = 1000
        val 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: TreeClickInterface

    fun 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.RecyclerView
        android: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 = adapter

        binding.recyclerView.layoutManager =
            LinearLayoutManager(this@EquipmentStateActivity, LinearLayoutManager.VERTICAL, false)


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


http://www.kler.cn/a/405289.html

相关文章:

  • 格式化输入输出【专辑优质版】
  • 贪心算法 -- 递增子序列
  • Vue 如何简单更快的对 TypeScript 中接口的理解?应用场景?
  • Compose Navigation快速入门
  • Matlab 答题卡方案
  • RPC安全可靠的异常重试
  • 【K8S系列】imagePullSecrets配置正确,但docker pull仍然失败,进一步排查详细步骤
  • java: spire.pdf.free 9.12.3 create pdf
  • Android 应用添加系统签名权限介绍
  • reactflow 中 useOnViewportChange 模块作用
  • 异构网络,赋能企业的智能连接
  • Next.js 入门指南:深入构建服务器渲染的现代 Web 应用
  • SpringBoot(二十七)SpringBoot集成XRebel实现异常定位
  • VMware 中 虚拟机【Linux系统】固定 ip 访问
  • 【Docker】Docker介绍|部署|简单使用|镜像操作|容器操作|自动构建镜像
  • 通过vite+vue3+pinia从0到1搭建一个uniapp应用
  • Element UI 组件库详解【Vue】
  • Ubuntu查看磁盘IO情况常用方法
  • Shell脚本2 -- 永久环境变量与字符串操作
  • 以太坊交易处理全流程:数据采集、价格查询与问题解决
  • Ubuntu问题 -- 设置ubuntu的IP为静态IP (图形化界面设置) 小白友好
  • 测试实项中的偶必现难测bug之模糊匹配逻辑
  • 基于IPMI_SSH的服务器硬件监控指标解读
  • Leetcode 完全二叉树的节点个数
  • application/json 和 application/x-www-form-urlencoded 区别
  • php:使用socket函数创建WebSocket服务