├── .gitignore
├── .idea
├── .gitignore
├── .name
├── compiler.xml
├── deploymentTargetSelector.xml
├── gradle.xml
├── kotlinc.xml
├── migrations.xml
├── misc.xml
├── runConfigurations.xml
└── vcs.xml
├── README.md
├── app
├── .gitignore
├── build.gradle.kts
├── proguard-rules.pro
└── src
│ ├── androidTest
│ └── java
│ │ └── org
│ │ └── fireking
│ │ └── xmind
│ │ └── ExampleInstrumentedTest.kt
│ ├── main
│ ├── AndroidManifest.xml
│ ├── java
│ │ └── org
│ │ │ └── fireking
│ │ │ └── xmind
│ │ │ ├── LayoutType.java
│ │ │ ├── LineStyle.java
│ │ │ ├── MainActivity.kt
│ │ │ ├── MindMapView.java
│ │ │ ├── MindNode.java
│ │ │ ├── layout
│ │ │ ├── BalancedLayoutStrategy.java
│ │ │ ├── HorizontalLayoutStrategy.java
│ │ │ ├── LayoutFactory.java
│ │ │ ├── LayoutStrategy.java
│ │ │ ├── RadialLayoutStrategy.java
│ │ │ ├── TreeLayoutStrategy.java
│ │ │ └── VerticalLayoutStrategy.java
│ │ │ └── model
│ │ │ └── MindNodeBuilder.java
│ └── res
│ │ ├── drawable
│ │ ├── ic_launcher_background.xml
│ │ └── ic_launcher_foreground.xml
│ │ ├── layout
│ │ └── activity_main.xml
│ │ ├── mipmap-anydpi-v26
│ │ ├── ic_launcher.xml
│ │ └── ic_launcher_round.xml
│ │ ├── mipmap-hdpi
│ │ ├── ic_launcher.webp
│ │ └── ic_launcher_round.webp
│ │ ├── mipmap-mdpi
│ │ ├── ic_launcher.webp
│ │ └── ic_launcher_round.webp
│ │ ├── mipmap-xhdpi
│ │ ├── ic_launcher.webp
│ │ └── ic_launcher_round.webp
│ │ ├── mipmap-xxhdpi
│ │ ├── ic_launcher.webp
│ │ └── ic_launcher_round.webp
│ │ ├── mipmap-xxxhdpi
│ │ ├── ic_launcher.webp
│ │ └── ic_launcher_round.webp
│ │ ├── values-night
│ │ └── themes.xml
│ │ ├── values
│ │ ├── colors.xml
│ │ ├── strings.xml
│ │ └── themes.xml
│ │ └── xml
│ │ ├── backup_rules.xml
│ │ └── data_extraction_rules.xml
│ └── test
│ └── java
│ └── org
│ └── fireking
│ └── xmind
│ └── ExampleUnitTest.kt
├── build.gradle.kts
├── gradle.properties
├── gradle
├── libs.versions.toml
└── wrapper
│ ├── gradle-wrapper.jar
│ └── gradle-wrapper.properties
├── gradlew
├── gradlew.bat
└── settings.gradle.kts
/.gitignore:
--------------------------------------------------------------------------------
1 | *.iml
2 | .gradle
3 | /local.properties
4 | /.idea/caches
5 | /.idea/libraries
6 | /.idea/modules.xml
7 | /.idea/workspace.xml
8 | /.idea/navEditor.xml
9 | /.idea/assetWizardSettings.xml
10 | .DS_Store
11 | /build
12 | /captures
13 | .externalNativeBuild
14 | .cxx
15 | local.properties
16 |
--------------------------------------------------------------------------------
/.idea/.gitignore:
--------------------------------------------------------------------------------
1 | # Default ignored files
2 | /shelf/
3 | /workspace.xml
4 |
--------------------------------------------------------------------------------
/.idea/.name:
--------------------------------------------------------------------------------
1 | XMind
--------------------------------------------------------------------------------
/.idea/compiler.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/.idea/deploymentTargetSelector.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
--------------------------------------------------------------------------------
/.idea/gradle.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
18 |
19 |
--------------------------------------------------------------------------------
/.idea/kotlinc.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/.idea/migrations.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
--------------------------------------------------------------------------------
/.idea/misc.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
--------------------------------------------------------------------------------
/.idea/runConfigurations.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
--------------------------------------------------------------------------------
/.idea/vcs.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # 🌳 Android Mind Map / Android 思维导图
2 |
3 |
4 |
5 | [](https://developer.android.com)
6 | [](https://kotlinlang.org)
7 | [](LICENSE)
8 |
9 | [English](#english) | [中文](#中文)
10 |
11 |
12 |
13 | ---
14 |
15 | ## 🌟 English
16 |
17 | ### 📱 Introduction
18 | An Android mind map application that supports multiple layout styles and interactive operations. Built with design patterns for better maintainability and extensibility.
19 |
20 | ### 🏗️ Architecture & Design Patterns
21 | - **Strategy Pattern**: Different layout algorithms implementation
22 | - **Factory Pattern**: Layout strategy creation
23 | - **Builder Pattern**: Mind map node construction
24 | - **Observer Pattern**: Node event handling
25 | - **MVC Pattern**: Basic project architecture
26 |
27 | ### 📂 Project Structure
28 | ```
29 | app/src/main/java/org/fireking/xmind/
30 | ├── layout/ # Layout strategies
31 | │ ├── LayoutStrategy.java # Layout strategy interface
32 | │ ├── LayoutFactory.java # Layout factory
33 | │ ├── HorizontalLayout.java # Horizontal layout implementation
34 | │ ├── VerticalLayout.java # Vertical layout implementation
35 | │ ├── RadialLayout.java # Radial layout implementation
36 | │ ├── TreeLayout.java # Tree layout implementation
37 | │ └── BalancedLayout.java # Balanced layout implementation
38 | ├── model/ # Data models
39 | │ └── MindNodeBuilder.java # Node builder
40 | ├── MindMapView.java # Custom view for mind map
41 | ├── MindNode.java # Node data structure
42 | ├── LayoutType.java # Layout type enum
43 | ├── LineStyle.java # Line style enum
44 | └── MainActivity.kt # Main activity
45 | ```
46 |
47 | ### ✨ Features
48 | - 📋 **Multiple Layout Styles**:
49 | - 🔄 Horizontal Layout
50 | - ↕️ Vertical Layout (Up/Down)
51 | - 🌟 Radial Layout (Clockwise/Anticlockwise)
52 | - 🌲 Tree Layout
53 | - ⚖️ Balanced Layout
54 | - 🎨 **Visual Effects**:
55 | - 🎯 Node Selection
56 | - 🌈 Gradient Colors
57 | - 💫 Smooth Animations
58 | - 🔧 **Interactive Operations**:
59 | - 👆 Node Click
60 | - ✋ Node Drag
61 | - 🔍 Zoom & Pan
62 | - 〽️ **Connection Styles**:
63 | - 📏 Straight Lines
64 | - 💫 Bezier Curves
65 |
66 | ### 📝 Usage Example
67 | ```kotlin
68 | // 1. Add MindMapView to your layout
69 |
73 |
74 | // 2. Create mind map in your activity
75 | class MainActivity : AppCompatActivity(), MindMapView.NodeEventListener {
76 | override fun onCreate(savedInstanceState: Bundle?) {
77 | super.onCreate(savedInstanceState)
78 | setContentView(R.layout.activity_main)
79 |
80 | mindMapView = findViewById(R.id.mindMapView)
81 | mindMapView.addNodeEventListener(this)
82 |
83 | // Create root node using builder pattern
84 | val rootNode = MindNodeBuilder("Android Development")
85 | .setPosition(screenWidth / 2, screenHeight / 2)
86 | .setLevel(0)
87 | .build()
88 |
89 | mindMapView.setRootNode(rootNode)
90 | }
91 |
92 | override fun onNodeClick(node: MindNode) {
93 | // Handle node click
94 | }
95 |
96 | override fun onNodeDrag(node: MindNode, dx: Float, dy: Float) {
97 | // Handle node drag
98 | }
99 | }
100 | ```
101 |
102 | ### ⚠️ Notes
103 | - 💻 Recommended for larger screens
104 | - 🚀 Consider performance with many nodes
105 | - 🔧 Adjust spacing parameters as needed
106 |
107 | ### 📅 Roadmap
108 | - [ ] 📝 Node editing
109 | - [ ] 💾 Data persistence
110 | - [ ] 📤 Import/Export
111 | - [ ] 🎨 Theme customization
112 | - [ ] ➕ More layout algorithms
113 |
114 | ---
115 |
116 | ## 🌟 中文
117 |
118 | ### 📱 简介
119 | 一个支持多种布局样式和交互操作的 Android 思维导图应用。采用设计模式构建,具有良好的可维护性和扩展性。
120 |
121 | ### 🏗️ 架构与设计模式
122 | - **策略模式**: 实现不同的布局算法
123 | - **工厂模式**: 创建布局策略
124 | - **建造者模式**: 构建思维导图节点
125 | - **观察者模式**: 处理节点事件
126 | - **MVC模式**: 基本项目架构
127 |
128 | ### 📂 项目结构
129 | ```
130 | app/src/main/java/org/fireking/xmind/
131 | ├── layout/ # 布局策略
132 | │ ├── LayoutStrategy.java # 布局策略接口
133 | │ ├── LayoutFactory.java # 布局工厂
134 | │ ├── HorizontalLayout.java # 水平布局实现
135 | │ ├── VerticalLayout.java # 垂直布局实现
136 | │ ├── RadialLayout.java # 辐射布局实现
137 | │ ├── TreeLayout.java # 树形布局实现
138 | │ └── BalancedLayout.java # 均衡布局实现
139 | ├── model/ # 数据模型
140 | │ └── MindNodeBuilder.java # 节点构建器
141 | ├── MindMapView.java # 自定义视图
142 | ├── MindNode.java # 节点数据结构
143 | ├── LayoutType.java # 布局类型枚举
144 | ├── LineStyle.java # 连线样式枚举
145 | └── MainActivity.kt # 主活动
146 | ```
147 |
148 | ### ✨ 功能特点
149 | - 📋 **多种布局样式**:
150 | - 🔄 水平布局
151 | - ↕️ 垂直布局(向上/向下)
152 | - 🌟 辐射布局(顺时针/逆时针)
153 | - 🌲 树形布局
154 | - ⚖️ 均衡布局
155 | - 🎨 **视觉效果**:
156 | - 🎯 节点选中
157 | - 🌈 渐变色彩
158 | - 💫 平滑动画
159 | - 🔧 **交互操作**:
160 | - 👆 节点点击
161 | - ✋ 节点拖拽
162 | - 🔍 缩放平移
163 | - 〽️ **连接样式**:
164 | - 📏 直线连接
165 | - 💫 贝塞尔曲线
166 |
167 | ### ⚠️ 注意事项
168 | - 💻 建议在较大屏幕设备上使用
169 | - 🚀 节点数量过多时注意性能影响
170 | - 🔧 可以通过调整间距参数优化显示效果
171 |
172 | ### 📅 后续规划
173 | - [ ] 📝 支持节点编辑
174 | - [ ] 💾 数据持久化
175 | - [ ] 📤 导入导出功能
176 | - [ ] 🎨 主题定制
177 | - [ ] ➕ 更多布局算法
178 |
179 | ---
180 |
181 |
182 |
183 | **Made with ❤️ by [FireKing]**
184 |
185 |
--------------------------------------------------------------------------------
/app/.gitignore:
--------------------------------------------------------------------------------
1 | /build
--------------------------------------------------------------------------------
/app/build.gradle.kts:
--------------------------------------------------------------------------------
1 | plugins {
2 | alias(libs.plugins.android.application)
3 | alias(libs.plugins.kotlin.android)
4 | }
5 |
6 | android {
7 | namespace = "org.fireking.xmind"
8 | compileSdk = 34
9 |
10 | defaultConfig {
11 | applicationId = "org.fireking.xmind"
12 | minSdk = 24
13 | targetSdk = 34
14 | versionCode = 1
15 | versionName = "1.0"
16 |
17 | testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
18 | }
19 |
20 | buildTypes {
21 | release {
22 | isMinifyEnabled = false
23 | proguardFiles(
24 | getDefaultProguardFile("proguard-android-optimize.txt"),
25 | "proguard-rules.pro"
26 | )
27 | }
28 | }
29 | compileOptions {
30 | sourceCompatibility = JavaVersion.VERSION_11
31 | targetCompatibility = JavaVersion.VERSION_11
32 | }
33 | kotlinOptions {
34 | jvmTarget = "11"
35 | }
36 | }
37 |
38 | dependencies {
39 |
40 | implementation(libs.androidx.core.ktx)
41 | implementation(libs.androidx.appcompat)
42 | implementation(libs.material)
43 | implementation(libs.androidx.activity)
44 | implementation(libs.androidx.constraintlayout)
45 | implementation(libs.androidx.core.animation)
46 | testImplementation(libs.junit)
47 | androidTestImplementation(libs.androidx.junit)
48 | androidTestImplementation(libs.androidx.espresso.core)
49 | }
--------------------------------------------------------------------------------
/app/proguard-rules.pro:
--------------------------------------------------------------------------------
1 | # Add project specific ProGuard rules here.
2 | # You can control the set of applied configuration files using the
3 | # proguardFiles setting in build.gradle.
4 | #
5 | # For more details, see
6 | # http://developer.android.com/guide/developing/tools/proguard.html
7 |
8 | # If your project uses WebView with JS, uncomment the following
9 | # and specify the fully qualified class name to the JavaScript interface
10 | # class:
11 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview {
12 | # public *;
13 | #}
14 |
15 | # Uncomment this to preserve the line number information for
16 | # debugging stack traces.
17 | #-keepattributes SourceFile,LineNumberTable
18 |
19 | # If you keep the line number information, uncomment this to
20 | # hide the original source file name.
21 | #-renamesourcefileattribute SourceFile
--------------------------------------------------------------------------------
/app/src/androidTest/java/org/fireking/xmind/ExampleInstrumentedTest.kt:
--------------------------------------------------------------------------------
1 | package org.fireking.xmind
2 |
3 | import androidx.test.platform.app.InstrumentationRegistry
4 | import androidx.test.ext.junit.runners.AndroidJUnit4
5 |
6 | import org.junit.Test
7 | import org.junit.runner.RunWith
8 |
9 | import org.junit.Assert.*
10 |
11 | /**
12 | * Instrumented test, which will execute on an Android device.
13 | *
14 | * See [testing documentation](http://d.android.com/tools/testing).
15 | */
16 | @RunWith(AndroidJUnit4::class)
17 | class ExampleInstrumentedTest {
18 | @Test
19 | fun useAppContext() {
20 | // Context of the app under test.
21 | val appContext = InstrumentationRegistry.getInstrumentation().targetContext
22 | assertEquals("org.fireking.xmind", appContext.packageName)
23 | }
24 | }
--------------------------------------------------------------------------------
/app/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
15 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
--------------------------------------------------------------------------------
/app/src/main/java/org/fireking/xmind/LayoutType.java:
--------------------------------------------------------------------------------
1 | package org.fireking.xmind;
2 |
3 | public enum LayoutType {
4 | HORIZONTAL, // 水平布局
5 | VERTICAL_DOWN, // 垂直向下布局
6 | VERTICAL_UP, // 垂直向上布局
7 | RADIAL_CLOCKWISE, // 顺时针辐射布局
8 | RADIAL_ANTICLOCKWISE,// 逆时针辐射布局
9 | TREE, // 树形布局
10 | BALANCED_HORIZONTAL, // 水平均匀布局
11 | BALANCED_VERTICAL // 垂直均匀布局
12 | }
--------------------------------------------------------------------------------
/app/src/main/java/org/fireking/xmind/LineStyle.java:
--------------------------------------------------------------------------------
1 | package org.fireking.xmind;
2 |
3 | public enum LineStyle {
4 | STRAIGHT, // 直线
5 | BEZIER // 贝塞尔曲线
6 | }
--------------------------------------------------------------------------------
/app/src/main/java/org/fireking/xmind/MainActivity.kt:
--------------------------------------------------------------------------------
1 | package org.fireking.xmind
2 |
3 | import android.os.Bundle
4 | import android.widget.Button
5 | import android.widget.Toast
6 | import androidx.appcompat.app.AppCompatActivity
7 | import org.fireking.xmind.model.MindNodeBuilder
8 |
9 | class MainActivity : AppCompatActivity(), MindMapView.NodeEventListener {
10 |
11 | private lateinit var mindMapView: MindMapView
12 | private lateinit var btnLineStyle: Button
13 |
14 | override fun onCreate(savedInstanceState: Bundle?) {
15 | super.onCreate(savedInstanceState)
16 | setContentView(R.layout.activity_main)
17 |
18 | mindMapView = findViewById(R.id.mindMapView)
19 | mindMapView.addNodeEventListener(this)
20 | btnLineStyle = findViewById(R.id.btnLineStyle)
21 |
22 | // 初始化布局按钮点击事件
23 | setupLayoutButtons()
24 |
25 | // 创建示例数据
26 | createDemoMindMap()
27 |
28 | // 确保初始状态是曲线
29 | mindMapView.setLineStyle(LineStyle.BEZIER)
30 | }
31 |
32 | private fun setupLayoutButtons() {
33 | // 布局按钮映射
34 | val layoutButtons = mapOf(
35 | R.id.btnHorizontal to LayoutType.HORIZONTAL,
36 | R.id.btnVerticalDown to LayoutType.VERTICAL_DOWN,
37 | R.id.btnVerticalUp to LayoutType.VERTICAL_UP,
38 | R.id.btnRadialClockwise to LayoutType.RADIAL_CLOCKWISE,
39 | R.id.btnRadialAnticlockwise to LayoutType.RADIAL_ANTICLOCKWISE,
40 | R.id.btnTree to LayoutType.TREE,
41 | R.id.btnBalancedHorizontal to LayoutType.BALANCED_HORIZONTAL,
42 | R.id.btnBalancedVertical to LayoutType.BALANCED_VERTICAL
43 | )
44 |
45 | // 设置布局按钮点击事件
46 | layoutButtons.forEach { (buttonId, layoutType) ->
47 | findViewById