308 lines
15 KiB
Markdown
308 lines
15 KiB
Markdown
|
|
# Android UI Redesign — Linear Style
|
|||
|
|
|
|||
|
|
## Design Language
|
|||
|
|
|
|||
|
|
参考 Linear.app 的设计语言:极简、高信息密度、深色主题、无多余装饰。
|
|||
|
|
告别"VPN 大圆按钮"的传统模板,走向工具型产品的质感。
|
|||
|
|
|
|||
|
|
## 核心原则
|
|||
|
|
|
|||
|
|
1. **信息密度优先** — 一屏展示最多有效信息,不浪费空间在装饰元素上
|
|||
|
|
2. **深色主题** — Linear 标志性的深灰背景 + 高对比度文字
|
|||
|
|
3. **微妙的层次** — 通过 subtle 的背景色差区分区域,不用卡片阴影
|
|||
|
|
4. **Monospace 数据** — IP、延迟、流量等技术数据用等宽字体
|
|||
|
|
5. **无圆角按钮** — 操作通过 inline 文字按钮或 icon 触发
|
|||
|
|
6. **状态用颜色** — 绿色=在线/连接,黄色=警告,红色=断开/错误,紫色=品牌色
|
|||
|
|
|
|||
|
|
## 色板
|
|||
|
|
|
|||
|
|
```
|
|||
|
|
Background: #0D0D0D (接近纯黑)
|
|||
|
|
Surface: #1A1A1A (卡片/列表背景)
|
|||
|
|
Surface Hover: #222222 (hover/pressed 状态)
|
|||
|
|
Border: #2A2A2A (subtle 分割线)
|
|||
|
|
Text Primary: #EDEDEF (主要文字,略带暖色)
|
|||
|
|
Text Secondary: #7C7C82 (次要文字)
|
|||
|
|
Text Tertiary: #4E4E52 (最弱文字)
|
|||
|
|
Accent Purple: #8B5CF6 (品牌色,交互高亮)
|
|||
|
|
Green: #22C55E (在线/成功)
|
|||
|
|
Yellow: #EAB308 (警告/中等延迟)
|
|||
|
|
Red: #EF4444 (断开/错误/高延迟)
|
|||
|
|
Blue: #3B82F6 (信息/链接)
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
## 字体
|
|||
|
|
|
|||
|
|
```
|
|||
|
|
Sans: Inter / system sans-serif (UI 文字)
|
|||
|
|
Mono: JetBrains Mono / system monospace (数据)
|
|||
|
|
Size: 12sp 默认,11sp 次要,14sp 标题,20sp 页面标题
|
|||
|
|
Weight: 400 normal,500 medium (标题/强调)
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
## Navigation
|
|||
|
|
|
|||
|
|
保持底部 3 tab,但视觉重新设计:
|
|||
|
|
|
|||
|
|
```
|
|||
|
|
┌────────────────────────────────────┐
|
|||
|
|
│ (content area) │
|
|||
|
|
├────────────────────────────────────┤
|
|||
|
|
│ ◉ Overview ◎ Nodes ◎ Config │ ← 底部导航,icon + label
|
|||
|
|
└────────────────────────────────────┘
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
- Tab 名称: Overview / Nodes / Config (更专业)
|
|||
|
|
- Icon: 线性风格,1.5dp stroke
|
|||
|
|
- Active: accent purple icon + white label
|
|||
|
|
- Inactive: text_tertiary
|
|||
|
|
|
|||
|
|
## Screen 1: Overview (原 Home)
|
|||
|
|
|
|||
|
|
不再是大圆按钮。改为信息面板 + 顶部状态栏。
|
|||
|
|
|
|||
|
|
```
|
|||
|
|
┌────────────────────────────────────┐
|
|||
|
|
│ Sing ● Online │ ← 顶栏: 品牌名 + 状态 dot + 文字
|
|||
|
|
├────────────────────────────────────┤
|
|||
|
|
│ │
|
|||
|
|
│ ┌────────────────────────────────┐ │
|
|||
|
|
│ │ CONNECTION │ │ ← section label (text_tertiary, 11sp, uppercase)
|
|||
|
|
│ │ │ │
|
|||
|
|
│ │ Node Tokyo-01 │ │ ← key-value pairs
|
|||
|
|
│ │ Server 1.2.3.4:443 │ │
|
|||
|
|
│ │ Protocol VLESS + Reality │ │
|
|||
|
|
│ │ Uptime 02:34:17 │ │
|
|||
|
|
│ └────────────────────────────────┘ │
|
|||
|
|
│ │
|
|||
|
|
│ ┌────────────────────────────────┐ │
|
|||
|
|
│ │ TRAFFIC │ │
|
|||
|
|
│ │ │ │
|
|||
|
|
│ │ ↑ 1.2 GB ↓ 8.7 GB │ │ ← 大字号流量统计
|
|||
|
|
│ │ ↑ 2.4 MB/s ↓ 12 MB/s │ │ ← 实时速率
|
|||
|
|
│ │ │ │
|
|||
|
|
│ │ Connections 47 active │ │
|
|||
|
|
│ └────────────────────────────────┘ │
|
|||
|
|
│ │
|
|||
|
|
│ ┌────────────────────────────────┐ │
|
|||
|
|
│ │ RECENT CONNECTIONS │ │
|
|||
|
|
│ │ │ │
|
|||
|
|
│ │ youtube.com proxy 12ms │ │ ← 最近连接列表 (内嵌)
|
|||
|
|
│ │ api.github.com proxy 45ms │ │
|
|||
|
|
│ │ baidu.com direct 3ms │ │
|
|||
|
|
│ │ ads.doubleclick block -- │ │
|
|||
|
|
│ │ │ │
|
|||
|
|
│ │ View all → │ │
|
|||
|
|
│ └────────────────────────────────┘ │
|
|||
|
|
│ │
|
|||
|
|
│ ┌──────────────┐ │
|
|||
|
|
│ │ Disconnect │ │ ← 底部操作按钮 (text button, red when connected)
|
|||
|
|
│ └──────────────┘ │
|
|||
|
|
│ │
|
|||
|
|
├────────────────────────────────────┤
|
|||
|
|
│ ◉ Overview ◎ Nodes ◎ Config │
|
|||
|
|
└────────────────────────────────────┘
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
**断开状态:**
|
|||
|
|
|
|||
|
|
```
|
|||
|
|
┌────────────────────────────────────┐
|
|||
|
|
│ Sing ○ Offline │
|
|||
|
|
├────────────────────────────────────┤
|
|||
|
|
│ │
|
|||
|
|
│ │
|
|||
|
|
│ Not connected │ ← 居中灰色文字
|
|||
|
|
│ Tokyo-01 selected │ ← 当前选中节点
|
|||
|
|
│ │
|
|||
|
|
│ ┌──────────────┐ │
|
|||
|
|
│ │ Connect │ │ ← accent purple 按钮
|
|||
|
|
│ └──────────────┘ │
|
|||
|
|
│ │
|
|||
|
|
├────────────────────────────────────┤
|
|||
|
|
│ ◉ Overview ◎ Nodes ◎ Config │
|
|||
|
|
└────────────────────────────────────┘
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
## Screen 2: Nodes (节点列表)
|
|||
|
|
|
|||
|
|
Linear 风格的列表 — 高密度、无卡片、hover 高亮。
|
|||
|
|
|
|||
|
|
```
|
|||
|
|
┌────────────────────────────────────┐
|
|||
|
|
│ Nodes 3 nodes │ ← 标题 + 计数
|
|||
|
|
│ ┌────────┐ ┌──────────┐ ⟳ + │ ← tab pills: Proxy | Tailscale | 测速 | 添加
|
|||
|
|
│ │ Proxy │ │Tailscale │ │
|
|||
|
|
│ └────────┘ └──────────┘ │
|
|||
|
|
├────────────────────────────────────┤
|
|||
|
|
│ │
|
|||
|
|
│ ● Tokyo-01 12ms │ ← active dot(green) + name + delay(green)
|
|||
|
|
│ vless | 1.2.3.4:443 │ ← subtitle (text_secondary, 11sp)
|
|||
|
|
│────────────────────────────────────│ ← subtle border, not divider
|
|||
|
|
│ ○ Singapore-02 156ms │ ← inactive dot(border only) + delay(yellow)
|
|||
|
|
│ trojan | 5.6.7.8:443 │
|
|||
|
|
│────────────────────────────────────│
|
|||
|
|
│ ○ HK-Premium 328ms │ ← delay(red)
|
|||
|
|
│ ss | 9.10.11.12:8388 │
|
|||
|
|
│────────────────────────────────────│
|
|||
|
|
│ │
|
|||
|
|
│ Tailscale tab: │
|
|||
|
|
│ ● station 100.64.0.1 │ ← online dot + hostname + IP
|
|||
|
|
│ linux | online │
|
|||
|
|
│────────────────────────────────────│
|
|||
|
|
│ ○ phone 100.64.0.2 │ ← offline dot
|
|||
|
|
│ android | 3h ago │
|
|||
|
|
│ │
|
|||
|
|
├────────────────────────────────────┤
|
|||
|
|
│ ◎ Overview ◉ Nodes ◎ Config │
|
|||
|
|
└────────────────────────────────────┘
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
**Node 操作** — 长按弹出 bottom sheet (不是 expand):
|
|||
|
|
```
|
|||
|
|
┌────────────────────────────────────┐
|
|||
|
|
│ Tokyo-01 │
|
|||
|
|
│ vless + reality | 1.2.3.4:443 │
|
|||
|
|
├────────────────────────────────────┤
|
|||
|
|
│ ● Set Active │
|
|||
|
|
│ ⟳ Test Latency │
|
|||
|
|
│ ✎ Edit │
|
|||
|
|
│ 🗑 Delete (red) │
|
|||
|
|
└────────────────────────────────────┘
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
**添加节点** — 底部 sheet:
|
|||
|
|
```
|
|||
|
|
┌────────────────────────────────────┐
|
|||
|
|
│ Import Nodes │
|
|||
|
|
├────────────────────────────────────┤
|
|||
|
|
│ 📋 Paste URI │ ← vless://, vmess://, ss://, trojan://
|
|||
|
|
│ 🔗 Subscription URL │
|
|||
|
|
│ {} JSON Import │
|
|||
|
|
│ ✎ Manual │
|
|||
|
|
└────────────────────────────────────┘
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
## Screen 3: Config (原 Settings)
|
|||
|
|
|
|||
|
|
分组列表,每组有 subtle header。不用 Material TextInputLayout,用更紧凑的 inline 样式。
|
|||
|
|
|
|||
|
|
```
|
|||
|
|
┌────────────────────────────────────┐
|
|||
|
|
│ Config │
|
|||
|
|
├────────────────────────────────────┤
|
|||
|
|
│ │
|
|||
|
|
│ ROUTING │ ← section header (11sp, text_tertiary)
|
|||
|
|
│ Mode Rule-based ▾ │ ← inline dropdown, not spinner
|
|||
|
|
│ │
|
|||
|
|
│ DNS │
|
|||
|
|
│ Remote tls://8.8.8.8 ✎ │ ← value + edit icon
|
|||
|
|
│ Local 223.5.5.5 ✎ │
|
|||
|
|
│ │
|
|||
|
|
│ GENERAL │
|
|||
|
|
│ Auto-connect ──● │ ← toggle, accent purple when on
|
|||
|
|
│ IPv6 ●── │
|
|||
|
|
│ Block Ads ──● │
|
|||
|
|
│ │
|
|||
|
|
│ RULES │
|
|||
|
|
│ Proxy domains 3 rules › │ ← tap → detail screen
|
|||
|
|
│ Direct domains 2 rules › │
|
|||
|
|
│ Block domains 0 rules › │
|
|||
|
|
│ │
|
|||
|
|
│ TAILSCALE │
|
|||
|
|
│ Enabled ──● │
|
|||
|
|
│ Auth key •••••••••• ✎ │
|
|||
|
|
│ Hostname my-phone ✎ │
|
|||
|
|
│ Accept routes ●── │
|
|||
|
|
│ │
|
|||
|
|
│ TOOLS │
|
|||
|
|
│ Active Connections › │
|
|||
|
|
│ Logs › │
|
|||
|
|
│ │
|
|||
|
|
│ ABOUT │
|
|||
|
|
│ Version 0.5 │
|
|||
|
|
│ Engine mini-sing │
|
|||
|
|
│ │
|
|||
|
|
├────────────────────────────────────┤
|
|||
|
|
│ ◎ Overview ◎ Nodes ◉ Config │
|
|||
|
|
└────────────────────────────────────┘
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
## Implementation Plan
|
|||
|
|
|
|||
|
|
### Phase 1: 基础框架 (迁移到 Compose)
|
|||
|
|
|
|||
|
|
XML 布局要实现 Linear 风格太费劲,建议迁移到 Jetpack Compose。理由:
|
|||
|
|
- 深色主题 + 自定义组件在 Compose 里实现更自然
|
|||
|
|
- 动画/过渡效果更容易
|
|||
|
|
- 代码量更少(Compose 比 XML + Fragment 减少约 40%)
|
|||
|
|
- 现在是重写 UI 的最佳时机
|
|||
|
|
|
|||
|
|
**改动:**
|
|||
|
|
1. `build.gradle.kts`: 添加 Compose 依赖 + BOM
|
|||
|
|
2. `Theme.kt`: 定义 Linear 风格色板 + 字体
|
|||
|
|
3. `MainActivity.kt`: 改为 `setContent {}` + Compose Navigation
|
|||
|
|
4. 删除所有 XML layouts
|
|||
|
|
|
|||
|
|
### Phase 2: 三个主屏
|
|||
|
|
|
|||
|
|
1. `OverviewScreen.kt` — 状态面板 + 流量统计 + 最近连接
|
|||
|
|
2. `NodesScreen.kt` — 节点列表 + tab + 底部 sheet 操作
|
|||
|
|
3. `ConfigScreen.kt` — 分组配置列表
|
|||
|
|
|
|||
|
|
### Phase 3: 二级页面
|
|||
|
|
|
|||
|
|
1. `ConnectionsScreen.kt` — 全部活跃连接
|
|||
|
|
2. `LogsScreen.kt` — 实时日志
|
|||
|
|
3. `EditNodeSheet.kt` — 编辑/添加节点的 bottom sheet
|
|||
|
|
4. `EditRulesScreen.kt` — 编辑自定义规则
|
|||
|
|
|
|||
|
|
### Phase 4: 细节打磨
|
|||
|
|
|
|||
|
|
1. 过渡动画(页面切换、连接状态变化)
|
|||
|
|
2. 实时数据更新(流量速率曲线?)
|
|||
|
|
3. 触感反馈(haptic on connect/disconnect)
|
|||
|
|
4. 图标替换为自定义 linear-style icon set
|
|||
|
|
|
|||
|
|
## Component Library
|
|||
|
|
|
|||
|
|
复用组件抽取:
|
|||
|
|
|
|||
|
|
```kotlin
|
|||
|
|
// 基础组件
|
|||
|
|
@Composable fun SectionHeader(title: String) // "ROUTING", "DNS" etc.
|
|||
|
|
@Composable fun KeyValueRow(key: String, value: String) // inline key-value
|
|||
|
|
@Composable fun ToggleRow(label: String, checked: Boolean, onToggle: (Boolean) -> Unit)
|
|||
|
|
@Composable fun NavigationRow(label: String, detail: String, onClick: () -> Unit)
|
|||
|
|
@Composable fun StatusDot(color: Color, size: Dp = 8.dp)
|
|||
|
|
|
|||
|
|
// 节点相关
|
|||
|
|
@Composable fun NodeRow(node: Node, isActive: Boolean, delay: Int?, onClick: () -> Unit)
|
|||
|
|
@Composable fun PeerRow(peer: TailscalePeer, onClick: () -> Unit)
|
|||
|
|
|
|||
|
|
// 连接相关
|
|||
|
|
@Composable fun ConnectionRow(conn: Connection)
|
|||
|
|
@Composable fun TrafficCard(upload: Long, download: Long, uploadRate: Long, downloadRate: Long)
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
## 文件变更预估
|
|||
|
|
|
|||
|
|
| 操作 | 文件 |
|
|||
|
|
|------|------|
|
|||
|
|
| 新建 | `ui/theme/Theme.kt`, `ui/theme/Color.kt`, `ui/theme/Type.kt` |
|
|||
|
|
| 新建 | `ui/components/*.kt` (6-8 个基础组件) |
|
|||
|
|
| 新建 | `ui/screens/OverviewScreen.kt` |
|
|||
|
|
| 新建 | `ui/screens/NodesScreen.kt` |
|
|||
|
|
| 新建 | `ui/screens/ConfigScreen.kt` |
|
|||
|
|
| 新建 | `ui/screens/ConnectionsScreen.kt` |
|
|||
|
|
| 新建 | `ui/screens/LogsScreen.kt` |
|
|||
|
|
| 新建 | `ui/sheets/NodeActionSheet.kt` |
|
|||
|
|
| 新建 | `ui/sheets/ImportSheet.kt` |
|
|||
|
|
| 重写 | `MainActivity.kt` (Compose entry) |
|
|||
|
|
| 保留 | 所有非 UI 代码 (VPN service, config, JNI, etc.) |
|
|||
|
|
| 删除 | 所有 `res/layout/*.xml` |
|
|||
|
|
| 删除 | 所有 Fragment 类 (`HomeFragment.kt` 等) |
|
|||
|
|
| 更新 | `build.gradle.kts` (Compose deps) |
|
|||
|
|
| 更新 | `colors.xml` → 仅保留 splash 需要的 |
|
|||
|
|
| 更新 | `themes.xml` → 仅保留 splash + Compose bridge |
|