mirror of
https://github.com/wwiinnddyy/LanMountainDesktop.git
synced 2026-06-20 23:54:26 +08:00
20 KiB
20 KiB
天气组件 Material Design 重设计计划
目标: 全面重构阑山桌面天气组件的视觉设计,遵循 Material Design 3 规范,参考 Google Weather、几何天气、Breez 天气和柠檬天气的设计语言。
当前状态分析
现有组件
- WeatherWidget - 基础天气(温度+天气状况+位置)
- ExtendedWeatherWidget - 扩展天气(含指标、逐小时、逐日预报)
- HourlyWeatherWidget - 逐小时天气
- MultiDayWeatherWidget - 多日天气
- WeatherClockWidget - 天气时钟
现有问题
- 排版层次不清晰,文字大小对比不够
- 布局过于紧凑,缺乏呼吸感
- 内部卡片使用简单纯色背景,缺乏 Material 风格
- 背景场景和前景内容缺乏深度分离
- 圆角和间距不统一
现有视觉系统
- 4套调色板:Google(默认)、Geometric、Breezy、LemonFlutter
- 动态背景场景:MaterialWeatherSceneControl 绘制渐变+装饰
- 图标系统:WeatherIconView + WeatherIconAssetResolver
设计方向
核心原则
- Material Design 3 - 使用 M3 的排版、颜色、间距和形状规范
- 信息层级清晰 - 大字体温度、次要信息弱化
- 呼吸感 - 合理的间距和留白
- 深度感 - 前景卡片与背景场景分离
- 圆角一致性 - 遵循 DesignCornerRadius 规范
参考风格
- Google Weather - 大字体温度、清晰层级、圆角卡片、柔和渐变
- 几何天气 - 几何装饰、现代感
- Breez - 清新留白、柔和色彩
- 柠檬天气 - 活泼明亮
具体改动计划
Task 1: 优化 MaterialWeatherPalette 和调色板系统
文件: LanMountainDesktop/Views/Components/MaterialWeatherVisualTheme.cs
改动:
- 调整所有调色板的对比度,确保文字可读性
- 优化背景渐变色彩,更加柔和自然
- 统一文字主色和次色的对比度比例
- 为每个风格增加
SurfaceColor和SurfaceVariantColor用于卡片背景
当前调色板字段:
public sealed record MaterialWeatherPalette(
Color BackgroundTop,
Color BackgroundBottom,
Color PrimaryShape,
Color SecondaryShape,
Color AccentShape,
Color TextPrimary,
Color TextSecondary,
Color SurfaceTint,
Color OverlayTint);
新增字段:
Color SurfaceColor, // 卡片表面色(低透明度白色/黑色)
Color SurfaceVariantColor, // 变体表面色
Color OutlineColor // 分割线/边框色
Task 2: 重构 WeatherWidget(基础天气组件)
文件:
LanMountainDesktop/Views/Components/WeatherWidget.axamlLanMountainDesktop/Views/Components/WeatherWidget.axaml.cs
设计目标:
- 大字体温度显示(类似 Google Weather)
- 天气状况文字清晰可读
- 位置和温度范围弱化显示
- 图标与文字对齐优化
XAML 改动:
<Border x:Name="RootBorder"
CornerRadius="{DynamicResource DesignCornerRadiusComponent}"
ClipToBounds="True">
<Grid>
<components:MaterialWeatherSceneControl x:Name="Scene" />
<Border x:Name="OverlayBorder" />
<!-- 主内容区 -->
<Grid x:Name="ContentGrid"
RowDefinitions="*,Auto"
Margin="20,16,20,14">
<!-- 上半区:温度 + 图标 -->
<Grid ColumnDefinitions="*,Auto">
<StackPanel VerticalAlignment="Center" Spacing="4">
<!-- 温度:超大字体 -->
<TextBlock x:Name="TemperatureTextBlock"
Text="--°"
FontSize="72"
FontWeight="Bold"
LineHeight="72" />
<!-- 天气状况 -->
<TextBlock x:Name="ConditionTextBlock"
Text="Loading"
FontSize="18"
FontWeight="SemiBold"
TextTrimming="CharacterEllipsis" />
</StackPanel>
<!-- 右侧图标 -->
<components:WeatherIconView x:Name="MainIcon"
Grid.Column="1"
Width="72"
Height="72"
HorizontalAlignment="Right"
VerticalAlignment="Center" />
</Grid>
<!-- 底部信息栏 -->
<Grid Grid.Row="1" ColumnDefinitions="*,Auto">
<TextBlock x:Name="LocationTextBlock"
Text="Weather"
FontSize="13"
FontWeight="Medium"
TextTrimming="CharacterEllipsis"
VerticalAlignment="Bottom" />
<TextBlock x:Name="RangeTextBlock"
Grid.Column="1"
Text="-- / --"
FontSize="13"
FontWeight="Medium"
HorizontalAlignment="Right"
VerticalAlignment="Bottom" />
</Grid>
</Grid>
</Grid>
</Border>
CS 改动:
- 调整响应式布局的字体缩放比例
- 更新颜色绑定使用新的调色板字段
Task 3: 重构 ExtendedWeatherWidget(扩展天气组件)
文件:
LanMountainDesktop/Views/Components/ExtendedWeatherWidget.axamlLanMountainDesktop/Views/Components/ExtendedWeatherWidget.axaml.cs
设计目标:
- 顶部区域:位置+温度+图标横向排列
- 指标区域:使用 Material 3 风格的标签卡片
- 逐小时预报:水平滚动卡片,时间+图标+温度
- 逐日预报:列表式布局,日期+图标+高低温
XAML 改动:
<Border x:Name="RootBorder"
CornerRadius="{DynamicResource DesignCornerRadiusComponent}"
ClipToBounds="True">
<Grid>
<components:MaterialWeatherSceneControl x:Name="Scene" />
<Border x:Name="OverlayBorder" />
<Grid x:Name="ContentGrid"
RowDefinitions="Auto,Auto,Auto,Auto"
Margin="20,16,20,14"
RowSpacing="12">
<!-- 顶部:位置 + 图标 + 温度 -->
<Grid ColumnDefinitions="*,Auto,Auto" VerticalAlignment="Center">
<StackPanel VerticalAlignment="Center">
<TextBlock x:Name="LocationTextBlock"
Text="Weather"
FontSize="13"
FontWeight="Medium"
TextTrimming="CharacterEllipsis"
Opacity="0.72" />
<TextBlock x:Name="ConditionTextBlock"
Text="Loading"
FontSize="16"
FontWeight="SemiBold"
TextTrimming="CharacterEllipsis" />
</StackPanel>
<components:WeatherIconView x:Name="MainIcon"
Grid.Column="1"
Width="56"
Height="56"
Margin="0,0,10,0" />
<TextBlock x:Name="TemperatureTextBlock"
Grid.Column="2"
Text="--°"
FontSize="56"
FontWeight="Bold"
VerticalAlignment="Center" />
</Grid>
<!-- 指标区域 -->
<UniformGrid x:Name="MetricGrid" Grid.Row="1" Rows="1" Columns="3" />
<!-- 逐小时预报 -->
<Border Grid.Row="2"
Background="{DynamicResource SurfaceColor}"
CornerRadius="{DynamicResource DesignCornerRadiusMd}"
Padding="10,8">
<UniformGrid x:Name="HourlyGrid" Rows="1" Columns="6" />
</Border>
<!-- 逐日预报 -->
<Border Grid.Row="3"
Background="{DynamicResource SurfaceColor}"
CornerRadius="{DynamicResource DesignCornerRadiusMd}"
Padding="10,8">
<UniformGrid x:Name="DailyGrid" Rows="1" Columns="5" />
</Border>
</Grid>
</Grid>
</Border>
CS 改动:
CreateMetric方法:使用圆角卡片,Material 3 风格标签BuildHourlyItems方法:改进卡片样式,统一圆角BuildDailyItems方法:改进卡片样式,统一圆角
Task 4: 重构 HourlyWeatherWidget(逐小时天气组件)
文件:
LanMountainDesktop/Views/Components/HourlyWeatherWidget.axamlLanMountainDesktop/Views/Components/HourlyWeatherWidget.axaml.cs
设计目标:
- 顶部简洁信息栏
- 逐小时预报使用 Material 卡片风格
- 时间、图标、温度垂直排列
XAML 改动:
<Border x:Name="RootBorder"
CornerRadius="{DynamicResource DesignCornerRadiusComponent}"
ClipToBounds="True">
<Grid>
<components:MaterialWeatherSceneControl x:Name="Scene" />
<Border x:Name="OverlayBorder" />
<Grid x:Name="ContentGrid"
RowDefinitions="Auto,*"
Margin="18,14"
RowSpacing="12">
<!-- 顶部信息栏 -->
<Grid ColumnDefinitions="Auto,*,Auto,Auto" VerticalAlignment="Center">
<TextBlock x:Name="TemperatureTextBlock"
Text="--°"
FontSize="42"
FontWeight="Bold"
VerticalAlignment="Center" />
<StackPanel Grid.Column="1" Margin="12,0,0,0" VerticalAlignment="Center">
<TextBlock x:Name="ConditionTextBlock"
Text="Loading"
FontSize="15"
FontWeight="SemiBold"
TextTrimming="CharacterEllipsis" />
<TextBlock x:Name="LocationTextBlock"
Text="Weather"
FontSize="12"
FontWeight="Medium"
Opacity="0.72"
TextTrimming="CharacterEllipsis" />
</StackPanel>
<TextBlock x:Name="RangeTextBlock"
Grid.Column="2"
Text="-- / --"
FontSize="12"
FontWeight="Medium"
VerticalAlignment="Center"
Opacity="0.72"
Margin="0,0,10,0" />
<components:WeatherIconView x:Name="MainIcon"
Grid.Column="3"
Width="48"
Height="48" />
</Grid>
<!-- 逐小时预报卡片容器 -->
<Border Grid.Row="1"
Background="{DynamicResource SurfaceColor}"
CornerRadius="{DynamicResource DesignCornerRadiusMd}"
Padding="8,6">
<UniformGrid x:Name="HourlyGrid" Rows="1" Columns="6" />
</Border>
</Grid>
</Grid>
</Border>
Task 5: 重构 MultiDayWeatherWidget(多日天气组件)
文件:
LanMountainDesktop/Views/Components/MultiDayWeatherWidget.axamlLanMountainDesktop/Views/Components/MultiDayWeatherWidget.axaml.cs
设计目标:
- 左侧:当前天气信息(图标+温度+状况+位置)
- 右侧:多日预报列表,使用行式布局
XAML 改动:
<Border x:Name="RootBorder"
CornerRadius="{DynamicResource DesignCornerRadiusComponent}"
ClipToBounds="True">
<Grid>
<components:MaterialWeatherSceneControl x:Name="Scene" />
<Border x:Name="OverlayBorder" />
<Grid x:Name="ContentGrid"
ColumnDefinitions="1.2*,1.6*"
Margin="18,14"
ColumnSpacing="14">
<!-- 左侧当前天气 -->
<StackPanel VerticalAlignment="Center" Spacing="6">
<components:WeatherIconView x:Name="MainIcon"
Width="64"
Height="64"
HorizontalAlignment="Left" />
<TextBlock x:Name="TemperatureTextBlock"
Text="--°"
FontSize="42"
FontWeight="Bold" />
<TextBlock x:Name="ConditionTextBlock"
Text="Loading"
FontSize="15"
FontWeight="SemiBold"
TextTrimming="CharacterEllipsis" />
<TextBlock x:Name="LocationTextBlock"
Text="Weather"
FontSize="12"
FontWeight="Medium"
Opacity="0.72"
TextTrimming="CharacterEllipsis" />
</StackPanel>
<!-- 右侧多日预报 -->
<Border Grid.Column="1"
Background="{DynamicResource SurfaceColor}"
CornerRadius="{DynamicResource DesignCornerRadiusMd}"
Padding="10,8">
<ItemsControl x:Name="DailyItemsControl" />
</Border>
</Grid>
</Grid>
</Border>
Task 6: 重构 WeatherClockWidget(天气时钟组件)
文件:
LanMountainDesktop/Views/Components/WeatherClockWidget.axamlLanMountainDesktop/Views/Components/WeatherClockWidget.axaml.cs
设计目标:
- 左侧:大字体时间+日期
- 右侧:天气图标+温度+状况
- 信息层级清晰
XAML 改动:
<Border x:Name="RootBorder"
CornerRadius="{DynamicResource DesignCornerRadiusComponent}"
ClipToBounds="True">
<Grid>
<components:MaterialWeatherSceneControl x:Name="Scene" />
<Border x:Name="OverlayBorder" />
<Grid x:Name="ContentGrid"
ColumnDefinitions="*,Auto"
Margin="18,12"
ColumnSpacing="12">
<!-- 左侧时间 -->
<StackPanel VerticalAlignment="Center" Spacing="2">
<TextBlock x:Name="TimeTextBlock"
Text="--:--"
FontSize="38"
FontWeight="Bold"
LineHeight="38" />
<TextBlock x:Name="DateTextBlock"
Text="Weather"
FontSize="12"
FontWeight="Medium"
Opacity="0.72"
TextTrimming="CharacterEllipsis" />
</StackPanel>
<!-- 右侧天气 -->
<StackPanel Grid.Column="1"
VerticalAlignment="Center"
HorizontalAlignment="Right"
Spacing="1">
<components:WeatherIconView x:Name="MainIcon"
Width="44"
Height="44"
HorizontalAlignment="Right" />
<TextBlock x:Name="TemperatureTextBlock"
Text="--°"
FontSize="20"
FontWeight="SemiBold"
HorizontalAlignment="Right" />
<TextBlock x:Name="ConditionTextBlock"
Text="Loading"
FontSize="11"
FontWeight="Medium"
HorizontalAlignment="Right"
TextTrimming="CharacterEllipsis"
MaxWidth="100"
Opacity="0.82" />
</StackPanel>
</Grid>
</Grid>
</Border>
Task 7: 更新 ExtendedWeatherWidget 的代码后置文件
文件: LanMountainDesktop/Views/Components/ExtendedWeatherWidget.axaml.cs
改动:
-
CreateMetric方法改进:- 使用
DesignCornerRadiusSm圆角 - 使用新的
SurfaceColor作为卡片背景 - 优化字体大小和间距
- 使用
-
BuildHourlyItems方法改进:- 使用
DesignCornerRadiusSm圆角 - 使用
SurfaceColor作为卡片背景 - 时间、图标、温度垂直排列,居中对齐
- 使用
-
BuildDailyItems方法改进:- 使用
DesignCornerRadiusSm圆角 - 使用
SurfaceColor作为卡片背景 - 日期、图标、高低温垂直排列
- 使用
Task 8: 更新 HourlyWeatherWidget 的代码后置文件
文件: LanMountainDesktop/Views/Components/HourlyWeatherWidget.axaml.cs
改动:
CreateChip方法改进:- 使用
DesignCornerRadiusSm圆角 - 使用
SurfaceColor作为卡片背景 - 优化垂直排列的间距
- 使用
Task 9: 更新 MultiDayWeatherWidget 的代码后置文件
文件: LanMountainDesktop/Views/Components/MultiDayWeatherWidget.axaml.cs
改动:
CreateRow方法改进:- 添加底部分割线(除最后一行)
- 优化列间距和对齐
- 高低温使用不同透明度区分
Task 10: 更新 MaterialWeatherVisualTheme 调色板
文件: LanMountainDesktop/Views/Components/MaterialWeatherVisualTheme.cs
改动:
-
为
MaterialWeatherPalette添加新字段:SurfaceColor- 用于卡片表面SurfaceVariantColor- 用于变体表面OutlineColor- 用于分割线
-
更新所有调色板生成方法:
ResolveGooglePaletteResolveGeometricPaletteResolveBreezyPaletteResolveLemonPalette
-
每个调色板需要为白天/夜晚模式提供合适的 SurfaceColor:
- 白天:低透明度白色(如
#14FFFFFF) - 夜晚:低透明度黑色(如
#1A000000)
- 白天:低透明度白色(如
Task 11: 构建和测试
命令:
dotnet build LanMountainDesktop.slnx -c Debug
dotnet test LanMountainDesktop.slnx -c Debug
验证清单:
- 所有天气组件正常编译
- 运行时无异常
- 4套视觉风格正常切换
- 响应式布局正常工作
- 圆角资源正确应用
文件改动汇总
| 文件 | 改动类型 | 说明 |
|---|---|---|
MaterialWeatherVisualTheme.cs |
修改 | 添加 SurfaceColor 等字段,更新所有调色板 |
WeatherWidget.axaml |
修改 | 重构布局,优化排版 |
WeatherWidget.axaml.cs |
修改 | 调整响应式布局和颜色绑定 |
ExtendedWeatherWidget.axaml |
修改 | 重构布局,添加卡片容器 |
ExtendedWeatherWidget.axaml.cs |
修改 | 改进卡片创建方法 |
HourlyWeatherWidget.axaml |
修改 | 重构布局,添加卡片容器 |
HourlyWeatherWidget.axaml.cs |
修改 | 改进卡片创建方法 |
MultiDayWeatherWidget.axaml |
修改 | 重构布局,添加卡片容器 |
MultiDayWeatherWidget.axaml.cs |
修改 | 改进行创建方法 |
WeatherClockWidget.axaml |
修改 | 重构布局,优化排版 |
WeatherClockWidget.axaml.cs |
修改 | 调整响应式布局 |
设计规范检查清单
- 所有组件根容器使用
DesignCornerRadiusComponent - 内部卡片使用
DesignCornerRadiusMd或DesignCornerRadiusSm - 不使用硬编码圆角值
- 文字对比度符合 VISUAL_SPEC 要求
- 间距使用一致的倍数(4px 基线)
- 字体层级:温度(64-72px) > 状况(16-18px) > 位置/范围(12-13px)