├── .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 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /.idea/gradle.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 18 | 19 | -------------------------------------------------------------------------------- /.idea/kotlinc.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | -------------------------------------------------------------------------------- /.idea/migrations.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 9 | 10 | -------------------------------------------------------------------------------- /.idea/misc.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 10 | -------------------------------------------------------------------------------- /.idea/runConfigurations.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 16 | 17 | -------------------------------------------------------------------------------- /.idea/vcs.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # 🌳 Android Mind Map / Android 思维导图 2 | 3 |
4 | 5 | [![Platform](https://img.shields.io/badge/platform-Android-green.svg)](https://developer.android.com) 6 | [![Language](https://img.shields.io/badge/language-Kotlin-blue.svg)](https://kotlinlang.org) 7 | [![License](https://img.shields.io/badge/license-Apache%202.0-blue.svg)](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