首页 > 其他分享 >实现树形菜单

实现树形菜单

时间:2024-05-28 19:57:41浏览次数:20  
标签:node 菜单 layout parent 实现 树形 TreeNode android RecyclerView

在 Android 中创建树形菜单(Tree View)有几种方法,可以根据你的需求选择合适的方式。这种结构通常用于展示层级关系的数据。一个常见的实现方式是使用 `RecyclerView` 配合自定义的适配器来创建树形菜单。

以下是一个简单的示例,展示如何在 Android 中创建树形菜单,并点击每个分类可以展开下一级菜单。

### 步骤 1:添加 RecyclerView 依赖

确保在你的 `build.gradle` 文件中添加了 RecyclerView 的依赖:

```gradle
dependencies {
implementation 'androidx.recyclerview:recyclerview:1.2.1'
}
```

### 步骤 2:定义数据模型

定义一个简单的数据模型来表示树形结构中的每个节点:

```kotlin
data class TreeNode(
val name: String,
val children: List<TreeNode>? = null,
var isExpanded: Boolean = false
)
```

### 步骤 3:创建布局文件

创建 RecyclerView 的布局文件,例如 `activity_main.xml`:

```xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">

<androidx.recyclerview.widget.RecyclerView
android:id="@+id/recyclerView"
android:layout_width="0dp"
android:layout_height="0dp"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
```

### 步骤 4:创建 RecyclerView 适配器

创建自定义适配器来处理树形结构的展示和展开功能:

```kotlin
class TreeAdapter(private val nodes: MutableList<TreeNode>) :
RecyclerView.Adapter<TreeAdapter.TreeViewHolder>() {

inner class TreeViewHolder(view: View) : RecyclerView.ViewHolder(view) {
val nameTextView: TextView = view.findViewById(R.id.node_name)
val expandImageView: ImageView = view.findViewById(R.id.expand_icon)
}

override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): TreeViewHolder {
val view = LayoutInflater.from(parent.context)
.inflate(R.layout.tree_node_item, parent, false)
return TreeViewHolder(view)
}

override fun onBindViewHolder(holder: TreeViewHolder, position: Int) {
val node = nodes[position]
holder.nameTextView.text = node.name
holder.expandImageView.visibility = if (node.children.isNullOrEmpty()) View.GONE else View.VISIBLE
holder.expandImageView.setImageResource(if (node.isExpanded) R.drawable.ic_collapse else R.drawable.ic_expand)

holder.itemView.setOnClickListener {
if (!node.children.isNullOrEmpty()) {
node.isExpanded = !node.isExpanded
if (node.isExpanded) {
nodes.addAll(position + 1, node.children)
notifyItemRangeInserted(position + 1, node.children.size)
} else {
nodes.removeAll(node.children)
notifyItemRangeRemoved(position + 1, node.children.size)
}
notifyItemChanged(position)
}
}
}

override fun getItemCount(): Int = nodes.size
}
```

### 步骤 5:创建节点布局文件

创建单个节点的布局文件 `tree_node_item.xml`:

```xml
<?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:orientation="horizontal"
android:padding="8dp">

<ImageView
android:id="@+id/expand_icon"
android:layout_width="24dp"
android:layout_height="24dp"
android:layout_gravity="center_vertical"
android:src="@drawable/ic_expand"
android:contentDescription="@null" />

<TextView
android:id="@+id/node_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:layout_marginStart="8dp"
android:text="Node Name"
android:textSize="16sp" />
</LinearLayout>
```

### 步骤 6: 设置 RecyclerView

在你的 `MainActivity` 中初始化并设置 RecyclerView:

```kotlin
class MainActivity : AppCompatActivity() {

private lateinit var recyclerView: RecyclerView
private lateinit var treeAdapter: TreeAdapter

override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)

recyclerView = findViewById(R.id.recyclerView)
recyclerView.layoutManager = LinearLayoutManager(this)

val treeData = generateSampleTreeData()
treeAdapter = TreeAdapter(treeData.toMutableList())
recyclerView.adapter = treeAdapter
}

private fun generateSampleTreeData(): List<TreeNode> {
return listOf(
TreeNode("Category 1", listOf(
TreeNode("Subcategory 1-1"),
TreeNode("Subcategory 1-2", listOf(
TreeNode("Subcategory 1-2-1"),
TreeNode("Subcategory 1-2-2")
))
)),
TreeNode("Category 2", listOf(
TreeNode("Subcategory 2-1"),
TreeNode("Subcategory 2-2")
))
)
}
}
```

### 总结

通过上述步骤,你可以创建一个简单的树形菜单,点击每个分类可以展开下一级菜单或显示当前菜单下的内容。你可以根据需要进一步自定义每个节点的布局和功能。例如,你可以为每个节点添加图标,或者在节点上添加更多信息。

标签:node,菜单,layout,parent,实现,树形,TreeNode,android,RecyclerView
From: https://www.cnblogs.com/litianyu1969/p/18218700

相关文章

  • JAVA计算机毕业设计基于SpringBoot框架的民俗文化交流与交易平台的设计与实现(附源码+s
    本系统(程序+源码)带文档lw万字以上 文末可获取一份本项目的java源码和数据库参考。系统程序文件列表开题报告内容研究背景在全球化的今天,文化交流日益频繁,民俗文化作为各国独特的文化符号,其传承与保护显得尤为重要。然而,传统的民俗文化交流方式受限于地域、时间等因素,难以......
  • java springboot基于Spring Boot的成都科会公司工资管理系统的设计与实现人事考勤管理
    前言......
  • 利用信息量集实现互斥访问
    进程A用来生成信号集,并将其初值设为1(运行顺序为进程A->B->C)/**@Author:[email protected]*@Date:2024-05-0817:20:41*@LastEditors:[email protected]*@LastEditTime:2024-05-2818:47:38*/#include<stdio.h>#include<stdlib.h>#include<sys/......
  • C++实现获取设备管理器中的设备信息
     C++实现获取设备管理器中的设备信息,基本调用了windowsAPI函数,除此之外,还引用了setupapi.lib库,代码如下所示://PrintDeviceInfo.cpp:定义控制台应用程序的入口点。//#include<stdio.h>#include<locale.h>#include<Windows.h>#include<setupapi.h>#pragmacomm......
  • C++实现删除打印机副本功能
     我们要实现此功能,首先需要获取到打印机的名称,其次是将获取到的打印机名称依次删除。一、获取打印机副本名称1.我们获取打印机副本名称,可以使用windowsAPI中的EnumPrinters函数,该函数可以枚举出我们电脑中的打印机设备信息,该函数使用方法如下:DWORDFlags=PRINTER_ENU......
  • C++实现dll文件的显示调用
    我们实现dll文件的显示调用,主要分为三个步骤:创建DLL、导出函数、使用DLL。其中离不开WindowsAPI函数,使用到了LoadLibrary、GetProcAddress、 FreeLibrary等,以下是一个简单的示例程展示整个过程。:1.创建DLLMyLibrary.h//MyLibrary.h#ifndefMY_LIBRARY_H#defineMY_LI......
  • C#中的事件聚合器实现方法
    概述:_对象之间的关系_是使代码库难以理解和难以维护的原因。为了更好地理解它,我们求助于马丁·福勒(MartinFowler):事件聚合器是间接的简单元素。在最简单的形式中,您可以让它注册到您感兴趣的所有源对象,并让所有目标对象注册到事件聚合器。事件聚合器通过将源对象中的任何事件传......
  • 翻译在线图片翻译什么工具好?这些帮你轻松实现
    经常出国旅行的朋友们会遇到一个难题:如何翻译那些外文标识和菜单?毕竟不是每个人都精通多种语言,也不是所有地方都提供翻译。因此,找到一种便捷的翻译工具就显得尤为重要。如今科技的发展为我们带来了解决方案——图片翻译功能。只需上传照片,就能翻译其中的外语。那么像这样图......
  • Python 文件操作指南:使用 open 和 with open 实现高效读写
    ......
  • 智能指针一些实现分析
    智能指针一些实现分析提供值传递但是指针语义的功能。通过指针占用并且对管理对象,在离开作用域时释放该对象。在使用上还有另外一个很好用的功能,精简了代码复杂度,管理的对象类可以省略以下的函数默认构造函数复制构造函数复制赋值函数比如有一个类Fd用于管理fd,并且拥......