Files

679 lines
18 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 布局规范
本文档详细说明组件布局规范,包括**安全区域**、间距系统、网格系统和响应式布局。
## 🎯 布局目标
良好的布局应该:
- ✅ 内容不会被截断或溢出
- ✅ 视觉元素对齐整齐
- ✅ 留白充足,不拥挤
- ✅ 适配不同的组件尺寸
- ✅ 易于维护和扩展
## 📐 安全区域Safe Area
### 什么是安全区域?
**安全区域**是组件内容必须保持的最小边距,确保内容不会紧贴组件边缘,保持视觉舒适度。
```
┌─────────────────────────────────────────┐
│ ◄─────── 16px 安全边距 ───────► │
│ ▲ │
│ │ ┌─────────────────────────────────┐ │ │
│ │ │ │ │ │
│ │ │ 这是内容安全区域 │ │ │
│ │ │ 所有内容都应该在这里 │ │ │
│ 16px│ 不要紧贴边缘 │ │ │
│ │ │ │ │ │
│ │ └─────────────────────────────────┘ │ │
│ ▼ │
│ ◄─────── 16px 安全边距 ───────► │
└─────────────────────────────────────────┘
```
### 安全区域标准
| 位置 | 最小边距 | 推荐边距 | 说明 |
|-----|---------|---------|------|
| **上边距** | 16px | 16-20px | 顶部内容到边缘 |
| **下边距** | 16px | 16-20px | 底部内容到边缘 |
| **左边距** | 16px | 16-24px | 左侧内容到边缘 |
| **右边距** | 16px | 16-24px | 右侧内容到边缘 |
### AXAML 实现
```xml
<!-- ✅ 正确:使用 Padding 创建安全区域 -->
<Border Background="{DynamicResource CardBackgroundBrush}"
CornerRadius="8"
Padding="16">
<!-- 内容区域 -->
<StackPanel Spacing="8">
<TextBlock Text="标题" FontSize="16"/>
<TextBlock Text="内容" FontSize="14"/>
</StackPanel>
</Border>
<!-- ✅ 使用设计资源 -->
<Border Background="{DynamicResource CardBackgroundBrush}"
CornerRadius="{DynamicResource DesignCornerRadiusComponent}"
Padding="{DynamicResource DesignPaddingComponent}">
<!-- 内容 -->
</Border>
<!-- ❌ 错误:没有安全边距 -->
<Border Background="{DynamicResource CardBackgroundBrush}"
CornerRadius="8">
<!-- 内容会紧贴边缘,不美观 -->
<TextBlock Text="标题"/>
</Border>
```
### 不同 Padding 配置
```xml
<!-- 统一边距 -->
<Border Padding="16">...</Border>
<!-- 左右、上下不同 -->
<Border Padding="16,12">...</Border>
<!-- 等价于: Left=Right=16, Top=Bottom=12 -->
<!-- 四个方向分别指定 -->
<Border Padding="16,12,16,20">...</Border>
<!-- 顺序: Left, Top, Right, Bottom -->
<!-- 使用 Thickness -->
<Border>
<Border.Padding>
<Thickness Left="16" Top="12" Right="16" Bottom="20"/>
</Border.Padding>
</Border>
```
### 安全区域示例
**天气组件示例**:
```xml
<Border Width="200" Height="150"
Background="{DynamicResource CardBackgroundBrush}"
CornerRadius="8"
Padding="16">
<Grid RowDefinitions="Auto,*,Auto">
<!-- 顶部:位置信息(距离顶边 16px -->
<TextBlock Grid.Row="0"
Text="📍 北京"
FontSize="14"/>
<!-- 中间:主要信息 -->
<StackPanel Grid.Row="1"
VerticalAlignment="Center"
HorizontalAlignment="Center">
<TextBlock Text="☀️" FontSize="48"/>
<TextBlock Text="25°C" FontSize="32"/>
</StackPanel>
<!-- 底部:操作按钮(距离底边 16px -->
<StackPanel Grid.Row="2"
Orientation="Horizontal"
HorizontalAlignment="Right"
Spacing="8">
<Button Content="🔄" Padding="8,4"/>
<Button Content="⚙️" Padding="8,4"/>
</StackPanel>
</Grid>
</Border>
```
**可视化布局**:
```
┌────────────────────────────────┐
│ ◄─── 16px ───► │ ▲
│ ▲ │ │
│ │ 📍 北京 │ │ 16px
│ │ │ │
│ │ ☀️ │ ▼
│ 16px 25°C │
│ │ 晴 │
│ │ │ ▲
│ │ [🔄] [⚙️] │ │ 16px
│ ▼ │ │
│ ◄─── 16px ───► │ ▼
└────────────────────────────────┘
```
## 📏 间距系统
### 间距标准
阑山桌面使用 **4px 基础网格**,所有间距都是 4 的倍数。
| 名称 | 值 | 用途 | 使用场景 |
|-----|---|------|---------|
| **XXS** | 2px | 最小间距 | 边框到内容、图标微调 |
| **XS** | 4px | 紧密间距 | 相邻标签、图标与文字 |
| **S** | 8px | 小间距 | 相关元素之间 |
| **M** | 12px | 中间距 | 元素组之间 |
| **L** | 16px | 大间距 | 区块之间、安全边距 |
| **XL** | 24px | 超大间距 | 重要区块分隔 |
| **XXL** | 32px | 巨大间距 | 页面级分隔 |
### 间距使用场景
#### 1. 垂直间距Vertical Spacing
```xml
<StackPanel Spacing="8">
<!-- 元素 1 -->
<TextBlock Text="标题"/>
<!-- ↕ 8px 间距 -->
<!-- 元素 2 -->
<TextBlock Text="内容"/>
<!-- ↕ 8px 间距 -->
<!-- 元素 3 -->
<Button Content="操作"/>
</StackPanel>
```
**垂直间距指南**:
```
相关元素(标题和内容): 8px
不同区块: 16px
独立功能区: 24px
示例:
┌──────────────────┐
│ 📍 北京 │ ← 标题
│ ↕ 8px │
│ 今天天气不错 │ ← 内容
│ ↕ 16px │ ← 区块分隔
│ ☀️ │
│ 25°C │
│ ↕ 16px │ ← 区块分隔
│ [刷新] [设置] │
└──────────────────┘
```
#### 2. 水平间距Horizontal Spacing
```xml
<StackPanel Orientation="Horizontal" Spacing="8">
<!-- 元素 1 -->
<Button Content="按钮1"/>
<!-- ↔ 8px 间距 -->
<!-- 元素 2 -->
<Button Content="按钮2"/>
</StackPanel>
```
**水平间距指南**:
```
图标和文字: 4px
相关按钮: 8px
独立按钮: 12px
示例:
[🔄] ← 4px → 刷新 ← 8px → [⚙️] ← 4px → 设置
```
#### 3. 网格间距Grid Spacing
```xml
<Grid ColumnDefinitions="*,8,*" RowDefinitions="*,8,*">
<!-- 列间距: 8px, 行间距: 8px -->
<Border Grid.Column="0" Grid.Row="0" Background="Red"/>
<Border Grid.Column="2" Grid.Row="0" Background="Blue"/>
<Border Grid.Column="0" Grid.Row="2" Background="Green"/>
<Border Grid.Column="2" Grid.Row="2" Background="Yellow"/>
</Grid>
```
### AXAML 间距资源
```xml
<!-- 定义间距资源 -->
<ResourceDictionary>
<Thickness x:Key="SpacingXXS">2</Thickness>
<Thickness x:Key="SpacingXS">4</Thickness>
<Thickness x:Key="SpacingS">8</Thickness>
<Thickness x:Key="SpacingM">12</Thickness>
<Thickness x:Key="SpacingL">16</Thickness>
<Thickness x:Key="SpacingXL">24</Thickness>
<Thickness x:Key="SpacingXXL">32</Thickness>
</ResourceDictionary>
<!-- 使用间距资源 -->
<Border Margin="{StaticResource SpacingL}">
<StackPanel Spacing="8">
<!-- 内容 -->
</StackPanel>
</Border>
```
## 🔲 网格系统
### 4px 基础网格
所有元素的位置、尺寸、间距都应该对齐到 **4px 的倍数**
```
0px 4px 8px 12px 16px 20px 24px 28px 32px
│ │ │ │ │ │ │ │ │
▼ ▼ ▼ ▼ ▼ ▼ ▼ ▼ ▼
┌─────┬─────┬─────┬─────┬─────┬─────┬─────┬─────┐
│ │ │ │ │ │ │ │ │
├─────┼─────┼─────┼─────┼─────┼─────┼─────┼─────┤
│ │ │ │ │ │ │ │ │
```
**为什么是 4px**
- ✅ 足够小,提供精细控制
- ✅ 是 8 和 16 的因子,便于计算
- ✅ 符合 Windows 11 设计规范
- ✅ 在高 DPI 屏幕上显示良好
### 对齐示例
```
❌ 错误:未对齐网格
┌──────────────┐
│ Padding: 15px│ ← 15 不是 4 的倍数
│ Width: 203px │ ← 203 不是 4 的倍数
└──────────────┘
✅ 正确:对齐到网格
┌──────────────┐
│ Padding: 16px│ ← 16 = 4 × 4
│ Width: 200px │ ← 200 = 4 × 50
└──────────────┘
```
### 常用尺寸
**符合 4px 网格的常用尺寸**:
| 用途 | 尺寸选项px |
|-----|---------------|
| **按钮高度** | 28, 32, 36, 40 |
| **图标尺寸** | 12, 16, 20, 24, 32, 48 |
| **组件宽度** | 120, 160, 200, 240, 280, 320, 400 |
| **组件高度** | 80, 120, 160, 200, 240, 280, 320 |
## 📦 组件尺寸规范
### 最小尺寸
```
┌─────────────────────┐
│ 最小宽度: 120px │
│ 最小高度: 80px │
│ │
│ 保证可读性和可用性 │
└─────────────────────┘
```
**最小尺寸要求**:
- ✅ 宽度 ≥ 120px - 保证文字不会过度换行
- ✅ 高度 ≥ 80px - 保证内容有足够空间
- ✅ 按钮 ≥ 32×32px - 保证可点击性
### 推荐尺寸
**小型组件120-150px**:
```
┌──────────────┐
│ 📍 北京 │
│ │
│ ☀️ │
│ 25°C │
└──────────────┘
120×80 - 150×100
适合: 单一信息、时钟、倒计时
```
**中型组件200-300px**:
```
┌────────────────────────┐
│ 📍 北京 │
│ │
│ ☀️ │
│ 25°C │
│ 晴 │
│ │
│ 今天: 18-30°C │
│ 湿度: 60% 风速: 3m/s │
│ │
│ [🔄] [⚙️] │
└────────────────────────┘
200×150 - 300×250
适合: 天气、日历、待办、便签
```
**大型组件350-500px**:
```
┌────────────────────────────────────────┐
│ 📅 本周日程 │
│ │
│ 周一 │
│ 09:00 - 10:00 团队会议 │
│ 14:00 - 15:30 项目评审 │
│ │
│ 周二 │
│ 10:00 - 11:00 客户沟通 │
│ ... │
│ │
│ [查看更多] │
└────────────────────────────────────────┘
350×300 - 500×400
适合: 日程、系统监控、新闻列表
```
### 宽高比建议
| 组件类型 | 推荐比例 | 示例尺寸 |
|---------|---------|---------|
| **正方形** | 1:1 | 120×120, 200×200 |
| **横向** | 4:3 | 200×150, 320×240 |
| **宽屏** | 16:9 | 320×180, 400×225 |
| **竖向** | 3:4 | 150×200, 240×320 |
## 🎯 响应式布局
### 尺寸适配
组件应该优雅地适配不同尺寸:
```csharp
public class WeatherComponent : ComponentBase
{
// 监听尺寸变化
protected override void OnSizeChanged(Size newSize)
{
if (newSize.Width < 180)
{
// 小尺寸:简化布局
ShowCompactLayout();
}
else if (newSize.Width < 300)
{
// 中等尺寸:标准布局
ShowNormalLayout();
}
else
{
// 大尺寸:详细布局
ShowDetailedLayout();
}
}
}
```
### 内容裁剪策略
**文本裁剪**:
```xml
<!-- 单行文本,超出显示省略号 -->
<TextBlock Text="这是一段很长的文字..."
TextTrimming="CharacterEllipsis"
MaxLines="1"/>
<!-- 多行文本,最多显示 2 行 -->
<TextBlock Text="这是一段很长的文字..."
TextWrapping="Wrap"
TextTrimming="CharacterEllipsis"
MaxLines="2"/>
```
**内容溢出处理**:
```xml
<!-- 使用 ScrollViewer 处理溢出 -->
<ScrollViewer MaxHeight="200"
VerticalScrollBarVisibility="Auto">
<ItemsControl ItemsSource="{Binding Items}">
<!-- 列表项 -->
</ItemsControl>
</ScrollViewer>
```
### 断点设计
| 断点名称 | 宽度范围 | 布局策略 |
|---------|---------|---------|
| **XS** | < 160px | 极简布局,只显示核心信息 |
| **S** | 160-240px | 简化布局,隐藏次要信息 |
| **M** | 240-360px | 标准布局,显示主要信息 |
| **L** | 360-480px | 详细布局,显示完整信息 |
| **XL** | > 480px | 丰富布局,显示扩展信息 |
### 响应式示例
**小尺寸(< 160px**:
```
┌──────────┐
│ ☀️ │
│ 25°C │
└──────────┘
只显示图标和温度
```
**中尺寸200px**:
```
┌────────────────┐
│ 📍 北京 │
│ │
│ ☀️ │
│ 25°C │
│ 晴 │
│ │
│ 🔄 ⚙️ │
└────────────────┘
显示位置、天气、操作
```
**大尺寸300px**:
```
┌──────────────────────────┐
│ 📍 北京 │
│ │
│ ☀️ │
│ 25°C │
│ 晴 │
│ │
│ 今天: 18-30°C │
│ 湿度: 60% 风速: 3m/s │
│ 空气质量: 良 │
│ │
│ [刷新] [设置] │
└──────────────────────────┘
显示详细信息
```
## 📐 对齐指南
### 水平对齐
```xml
<!-- 左对齐 -->
<StackPanel HorizontalAlignment="Left">
<TextBlock Text="左对齐"/>
</StackPanel>
<!-- 居中对齐 -->
<StackPanel HorizontalAlignment="Center">
<TextBlock Text="居中对齐"/>
</StackPanel>
<!-- 右对齐 -->
<StackPanel HorizontalAlignment="Right">
<TextBlock Text="右对齐"/>
</StackPanel>
<!-- 拉伸(占满宽度) -->
<StackPanel HorizontalAlignment="Stretch">
<TextBlock Text="拉伸"/>
</StackPanel>
```
### 垂直对齐
```xml
<!-- 顶部对齐 -->
<Grid>
<StackPanel VerticalAlignment="Top">
<TextBlock Text="顶部"/>
</StackPanel>
</Grid>
<!-- 居中对齐 -->
<Grid>
<StackPanel VerticalAlignment="Center">
<TextBlock Text="居中"/>
</StackPanel>
</Grid>
<!-- 底部对齐 -->
<Grid>
<StackPanel VerticalAlignment="Bottom">
<TextBlock Text="底部"/>
</StackPanel>
</Grid>
```
### 对齐最佳实践
```
✅ 好的对齐:
┌──────────────────┐
│ 标题 │ ← 左对齐
│ │
│ 25°C │ ← 居中对齐
│ │
│ [按钮] │ ← 右对齐
└──────────────────┘
❌ 差的对齐:
┌──────────────────┐
│ 标题 │ ← 随意对齐
│ │
│ 25°C │ ← 不一致
│ │
│ [按钮] │ ← 混乱
└──────────────────┘
```
## 🛠️ 实用工具
### 布局调试
```xml
<!-- 开发时显示边界 -->
<Border BorderBrush="Red" BorderThickness="1">
<StackPanel>
<!-- 内容 -->
</StackPanel>
</Border>
<!-- 显示网格线 -->
<Grid ShowGridLines="True">
<!-- 内容 -->
</Grid>
```
### 布局助手类
```csharp
public static class LayoutHelper
{
// 对齐到 4px 网格
public static double AlignToGrid(double value)
{
return Math.Round(value / 4) * 4;
}
// 计算安全区域
public static Thickness SafeArea(double padding = 16)
{
return new Thickness(padding);
}
// 响应式尺寸
public static bool IsCompact(double width)
{
return width < 180;
}
public static bool IsNormal(double width)
{
return width >= 180 && width < 300;
}
public static bool IsExpanded(double width)
{
return width >= 300;
}
}
```
## ✅ 布局检查清单
发布前请检查:
### 安全区域
- [ ] 上下左右至少 16px 边距
- [ ] 内容不会紧贴边缘
- [ ] 圆角区域没有被裁切
### 间距
- [ ] 使用 4px 基础网格
- [ ] 相关元素间距 8px
- [ ] 区块间距 16px
- [ ] 间距统一一致
### 尺寸
- [ ] 最小宽度 ≥ 120px
- [ ] 最小高度 ≥ 80px
- [ ] 按钮尺寸 ≥ 32×32px
- [ ] 尺寸是 4 的倍数
### 对齐
- [ ] 元素精确对齐
- [ ] 左右边距对称
- [ ] 文字基线对齐
- [ ] 视觉平衡
### 响应式
- [ ] 小尺寸下正常显示
- [ ] 大尺寸下充分利用空间
- [ ] 文本溢出正确处理
- [ ] 图片按比例缩放
## 📖 相关文档
- [视觉规范](02-视觉规范.md) - 颜色、字体、图标
- [交互规范](04-交互规范.md) - 交互状态和动画
- [组件系统](../01-插件开发/02-核心概念/02-组件系统.md) - 组件开发
- [天气组件案例](../01-插件开发/04-实战案例/01-天气组件.md) - 完整示例
---
**记住**: 安全区域 16px间距基于 4px 网格,一切对齐精确。