HarmonyOS 6.1 全场景实战|《灵犀厨房一键推荐》元服务【架构篇】常量体系:从硬编码地狱到原子化设计的架构跃迁

摘要:开发调试阶段,我的《灵犀厨房一键推荐》元服务里,'#FF6B35' 写了 23 次、'{ padding: 20 }' 写了 17 次、'灵犀厨房' 写了 8 次——改一个"换一道"按钮文案要翻 6 个文件,改主色调要全局搜索替换 30+ 处。你可能觉得"不就是几个颜色和尺寸嘛,直接写上去多省事"。但当你的元服务同时运行在手机、折叠屏、平板三种形态上,设计师说"主色调微调 2 度",你就知道什么叫"牵一色而动全身"。本篇将基于 HarmonyOS 6.1.0(API 23),从设计系统的原子化哲学出发,带你完成一场"一行常量,全网统一"的架构升级。


一、引言:从"配色霰弹枪"到"原子级设计系统"

《灵犀厨房一键推荐》作为 HarmonyOS 全场景应用,核心能力是"一键推荐菜谱"。产品迭代过程中,UI 逐渐丰富——季节提示区、毛玻璃协议页、Hero 卡片动画、候选菜谱列表。每加一个视觉元素,顺手就写一组颜色值和尺寸:

场景 痛点 后果
设计师调色 '#FF6B35' 散落在 8 个文件中 逐个文件替换,漏一处就出现"阴阳配色"
多设备适配 硬编码 width: 140radius: 22 折叠屏展开后按钮奇大无比,平板上一行放不下两个卡片
文案修改 “换一道"改成"不感兴趣” 按钮上改了,日志里还是"换一道",排查时一头雾水
新人接手 不知道 'rgba(255,255,255,0.25)' 是什么语义 不敢改颜色,怕破坏毛玻璃效果
组件复用 每个页面自己写一套间距 页面间视觉节奏感不一致,用户感知粗糙

AppConstants 原子常量体系的解决方案

🎯 AppColors.Primary 一次性定义主色 → 全域 30+ 处自动统一。AppTexts.Retry 一处修改文案 → 按钮、日志、埋点同步更新。AppDimensions.xxx 四级间距体系统一 → 多设备形态自动协调。常量即文档,类名即语义。

为什么这是"原子级"设计? 就像乐高积木——你不需要知道每块积木的化学成分,只需要知道红色积木叫"Red Brick"。设计师说"主色调调亮一度",你只需要改 AppColors.Primary 这一个原子,整个系统的所有组件自动继承新颜色。这就是设计系统的"原子化"哲学:最小的设计单元,最大的复用价值


二、核心原理:原子化设计的四字真言

2.1 旧体系的"霰弹枪式布局"

在引入 AppConstants 之前,《灵犀厨房》的 Index.ets 中充斥着大量裸值:

// ❌ 修复前:散弹枪式硬编码
Column({ space: 8 })                     // 8 是什么意思?间距XS?还是偶然值?
  .borderRadius(28)                       // 28 是什么圆角等级?卡片?按钮?
  .backgroundColor('#FF6B35')            // 主色?警告色?品牌色?
  .padding({ left: 20, right: 20 })      // 20 是页面边距还是卡片边距?

核心矛盾:值本身无法表达设计意图。8 可以是间距 XS、弹窗内边距、图标与文字的 gap。28 是卡片圆角级别还是某个特殊半径?裸值不具备"可解释性"——它们像散落在地板上的子弹,每一颗单独看都认识,但没有任何一颗告诉你"我应该被装进哪把枪"。

2.2 AppConstants 的四层原子化设计

🎨 UI组件层

🎨 设计令牌四层体系

AppColors
色板层

语义化色彩
Primary / Secondary / TextWhite85

AppDimensions
尺度层

分级尺寸
SpacingXS / RadiusCard / ButtonHeight

AppAnimations
动效层

时长/缓动
DurationEnter / ScalePressed

AppTexts / SeasonHints
内容层

文案/Emoji
Retry / Spring / SpringEmoji

Button
backgroundColor=Primary
borderRadius=RadiusXL

HeroCard
padding=PaddingPage
shadow=ShadowConfig

毛玻璃层
GlassGradientStart
backgroundBlurStyle

季节提示
SeasonHints.Spring
SeasonHints.SpringEmoji

核心代码实现

// ============================================================
// 层级:Infrastructure(基础设施层)— 原子常量体系
// 设计理念:轻·透·跨·智 —— 轻盈的常量定义,透明的语义传递
//          跨层级复用,智能的设计系统
// ============================================================

// 色板层 —— "语义化"替代"裸色值"
export class AppColors {
  static readonly Primary: string = '#FF6B35';        // 主品牌色
  static readonly PrimaryLight: string = '#FF8A5C';    // 主色浅变体(按压态)
  static readonly PrimaryDark: string = '#E85D26';     // 主色深变体(深色模式)
  static readonly GlassGradientStart: string = 'rgba(255,255,255,0.95)'; // 毛玻璃渐变起点
  static readonly GlassGradientMiddle: string = 'rgba(245,245,247,0.9)'; // 毛玻璃渐变中段
  static readonly GlassGradientEnd: string = 'rgba(240,240,242,0.85)';   // 毛玻璃渐变终点
  static readonly TextWhite85: string = 'rgba(255,255,255,0.85)';        // 半透白文本
  static readonly TextWhite60: string = 'rgba(255,255,255,0.60)';        // 次要半透白
  static readonly ShadowLight: string = 'rgba(0,0,0,0.08)';              // 轻阴影
  static readonly ShadowMedium: string = 'rgba(0,0,0,0.12)';             // 中阴影
  static readonly ShadowHeavy: string = 'rgba(0,0,0,0.20)';              // 重阴影
}

// 尺度层 —— "分级标签"替代"魔术数字"
export class AppDimensions {
  // 四级间距体系(适配新空间设计指南的层级节奏)
  static readonly SpacingXS: number = 4;    // 极小:图标与文字间距
  static readonly SpacingSM: number = 8;    // 小:组件内部元素间距
  static readonly SpacingMD: number = 12;   // 中:列表项间距
  static readonly SpacingLG: number = 16;   // 大:卡片内边距
  static readonly SpacingXL: number = 20;   // 超大:页面边距
  static readonly SpacingXXL: number = 24;  // 特大:区块间距
  static readonly SpacingXXXL: number = 32; // 最大:大区块分隔
  
  // 圆角体系(遵循新空间设计指南的圆角语义)
  static readonly RadiusSM: number = 8;     // 小圆角:标签/徽章
  static readonly RadiusMD: number = 12;    // 中圆角:内部卡片
  static readonly RadiusLG: number = 16;    // 大圆角:次级卡片
  static readonly RadiusXL: number = 28;    // 超大圆角:主卡片/Hero
  static readonly RadiusFull: number = 999; // 全圆角:胶囊按钮
  
  // 按钮尺寸(跨设备统一)
  static readonly ButtonHeight: number = 48;    // 主要按钮高度
  static readonly ButtonSmallHeight: number = 36; // 次要按钮高度
  static readonly ButtonMinWidth: number = 100;  // 按钮最小宽度
  
  // 页面边距(响应式断点适配)
  static readonly PaddingPage: number = 20;     // 页面标准边距
  static readonly PaddingPageSM: number = 12;   // 小屏设备边距
  static readonly PaddingPageLG: number = 32;   // 大屏设备边距
  
  // 卡片尺寸
  static readonly CardHeightHero: number = 220; // Hero 卡片高度
  static readonly CardHeightNormal: number = 180; // 普通卡片高度
}

// 动效层 —— "时长常量"替代"魔法毫秒"
export class AppAnimations {
  static readonly DurationInstant: number = 100;   // 瞬时反馈(按压态)
  static readonly DurationFast: number = 200;      // 快速过渡(Hover/点击)
  static readonly DurationNormal: number = 350;    // 标准过渡(页面切换)
  static readonly DurationEnter: number = 500;     // 入场动画(Hero卡片渐入)
  static readonly DurationExit: number = 300;      // 退场动画
  
  static readonly ScalePressed: number = 0.92;     // 按压缩放系数
  static readonly ScaleHover: number = 0.98;       // Hover缩放系数
  
  static readonly SpringStiffness: number = 300;   // 弹簧刚度(物理动画)
  static readonly SpringDamping: number = 25;      // 弹簧阻尼
}

// 内容层 —— "文本令牌"替代"硬编码字符串"
export class AppTexts {
  static readonly AppName: string = '灵犀厨房';
  static readonly Retry: string = '重新加载';
  static readonly ChangeRecipe: string = '换一道';
  static readonly NoData: string = '暂无推荐,下拉刷新试试';
  static readonly Loading: string = 'AI 正在识别食材...';
  static readonly PrivacyAgree: string = '我已阅读并同意';
  static readonly PrivacyProtocol: string = '《隐私协议》';
  static readonly SeasonHintLabel: string = '🍃 当季推荐';
}

// 季节提示(内容动态化)
export class SeasonHints {
  static readonly Spring: string = '春日宜清淡,荠菜、春笋正当季';
  static readonly SpringEmoji: string = '🌿';
  static readonly Summer: string = '夏日消暑,冬瓜、苦瓜正当时';
  static readonly SummerEmoji: string = '☀️';
  static readonly Autumn: string = '秋日润燥,银耳、雪梨正当时';
  static readonly AutumnEmoji: string = '🍂';
  static readonly Winter: string = '冬日暖身,羊肉、萝卜正当时';
  static readonly WinterEmoji: string = '❄️';
}

// 阴影配置(结构化,替代裸参数)
export interface ShadowConfig {
  radius: number;
  color: string;
  offsetX: number;
  offsetY: number;
}

export class AppShadows {
  static readonly CardLight: ShadowConfig = {
    radius: 4,
    color: 'rgba(0,0,0,0.06)',
    offsetX: 0,
    offsetY: 1
  };
  static readonly CardMedium: ShadowConfig = {
    radius: 8,
    color: 'rgba(0,0,0,0.08)',
    offsetX: 0,
    offsetY: 2
  };
  static readonly CardHeavy: ShadowConfig = {
    radius: 16,
    color: 'rgba(0,0,0,0.12)',
    offsetX: 0,
    offsetY: 4
  };
  static readonly Hero: ShadowConfig = {
    radius: 24,
    color: 'rgba(255,107,53,0.20)',
    offsetX: 0,
    offsetY: 8
  };
}

四层原子化逻辑图

✨ 产出:UI组件

📝 第四层:内容 (AppTexts/SeasonHints)

🎬 第三层:动效 (AppAnimations)

📐 第二层:尺度 (AppDimensions)

🧩 第一层:色板 (AppColors)

Primary

GlassGradientStart

TextWhite85

SpacingXS

RadiusXL

ButtonHeight

DurationEnter

ScalePressed

Retry

Spring

SpringEmoji

Button 按钮

HeroCard 英雄卡片

毛玻璃层

季节提示

💡 核心精髓static readonly 属性在 ArkTS 编译后是真正的编译时常量,引擎直接内联为字面值。AppColors.Primary 在运行时的开销 等于直接用 '#FF6B35'——零额外开销,百倍可维护性。这符合轻·透·跨·智中"轻"的设计哲学——轻盈的代码结构,不增加运行时负担。


三、分层架构:常量体系的四层渗透

按照《灵犀厨房》的四层架构,AppConstants 作为 Infrastructure 层(基础设施层) 的设计令牌,被所有上层模块单向依赖。这种"自上而下"的依赖方向确保了设计系统的唯一真理来源(Single Source of Truth)

⚙️ Services 层

📊 ViewModel 层

🎨 UI 层

📦 Infrastructure 层(设计令牌·原子库)

AppColors
色板原子

AppDimensions
尺度原子

AppAnimations
动效原子

AppTexts
内容原子

Index.ets
HeroCard / 季节提示

RecipeDetailPage.ets
详情页布局

ProfileTabContent.ets
个人中心

HomeViewModel
状态提示文案

Logger
模块标识

分层职责表

层级 消费者 典型引用 设计意图
UI 层 Index.ets(页面/组件) AppColors.PrimaryAppDimensions.SpacingMDAppTexts.Retry 视觉呈现的直接驱动者
ViewModel 层 状态管理 AppTexts.LoadingAppTexts.NoData 错误提示文案统一
Services 层 服务能力 Logger.info(TAG, ...)(日志中的 module 标识) 日志标识统一管理
Business 层 业务流程 推荐引擎的季节权重可引用 SeasonHints 业务逻辑与设计令牌联动

核心设计原则:Infrastructure 层不依赖任何上层模块,但所有上层模块都可以依赖它。这就像建筑设计中的"地基"——地基不需要知道上面盖的是别墅还是写字楼,但任何建筑都必须站在地基上。


四、关键实现步骤:从"散弹"到"原子"的迁移实战

Step 1:创建四层常量体系

entry/src/main/ets/constants/AppConstants.ets 中创建四大静态类。

设计决策矩阵

设计决策 具体选择 理由
封装形式 static readonly 静态类 编译时常量,零运行时开销,比 enum 支持更丰富的数据类型
颜色语义层级 按用途分类(主色/文本/背景/阴影/透明) 比按"颜色名"分类更贴近设计系统,符合"设计令牌"理念
间距分级策略 XS-SM-MD-LG-XL-XXL-XXXL 七档 覆盖 99% 场景,比 T-shirt Sizing 更精确,符合新空间设计指南的层级节奏
阴影抽象 ShadowConfig 接口 结构化参数,比三个裸 number 更不易出错,语义清晰
常量文件拆分 单文件(当前 < 200 行) 避免过度工程化,后续达到 500+ 行时再按领域拆分

Step 2:重构 Index.ets 中的硬编码

迁移对照表

原硬编码 新常量 语义提升 影响范围
'#FF6B35' AppColors.Primary “橙色字符串” → “主品牌色令牌” 全局 23 处
'rgba(255,255,255,0.85)' AppColors.TextWhite85 “半透明白数字” → “85% 不透明白文本” 全局 5 处
padding: { left: 20, right: 20 } padding: { left: AppDimensions.PaddingPage, right: AppDimensions.PaddingPage } “20px 硬编码” → “页面标准边距” 全局 17 处
.borderRadius(28) .borderRadius(AppDimensions.RadiusXL) “28 无意义数字” → “XL 级圆角(超大卡片)” 全局 8 处
'重新加载' AppTexts.Retry “硬编码中文” → “重试按钮文案令牌” 全局 3 处
'🌿' SeasonHints.SpringEmoji “裸 Emoji” → “春季标识 Emoji,附带语义” 全局 2 处

实际重构代码对比(Index.ets 节选)

// ❌ 修复前:28 处硬编码散落在 220 行代码中
@Entry
@Component
struct Index {
  build() {
    Column() {
      // Hero 卡片区域
      Row() {
        Button('重新加载')
          .fontSize(16)
          .height(48)
          .backgroundColor('#FF6B35')
          .borderRadius(24)
          .width(140)
          .onClick(() => this.reloadData())
        
        Text('🍃 当季推荐')
          .fontSize(14)
          .fontColor('rgba(255,255,255,0.85)')
      }
      .padding({ left: 20, right: 20 })
      .borderRadius(28)
      .backgroundColor('#FF6B35')
      
      // 季节提示区
      Row() {
        Text('🌿')
          .fontSize(20)
        Text('春日宜清淡,荠菜、春笋正当季')
          .fontSize(13)
          .fontColor('rgba(255,255,255,0.85)')
      }
      .padding({ left: 20, right: 20 })
    }
  }
}

// ✅ 修复后:全部替换为语义化常量,一行 import 引入,全局统一
import { 
  AppColors, 
  AppDimensions, 
  AppAnimations, 
  AppTexts, 
  SeasonHints 
} from '../constants/AppConstants';

@Entry
@Component
struct Index {
  build() {
    Column() {
      // Hero 卡片区域
      Row() {
        Button(AppTexts.Retry)
          .fontSize(AppDimensions.FontXXL)
          .height(AppDimensions.ButtonHeight)
          .backgroundColor(AppColors.Primary)
          .borderRadius(AppDimensions.RadiusXL)
          .width(140)  // 场景特定值保留,非通用设计令牌
          .onClick(() => this.reloadData())
        
        Text(AppTexts.SeasonHintLabel)
          .fontSize(AppDimensions.FontMD)
          .fontColor(AppColors.TextWhite85)
      }
      .padding({ 
        left: AppDimensions.PaddingPage, 
        right: AppDimensions.PaddingPage 
      })
      .borderRadius(AppDimensions.RadiusXL)
      .backgroundColor(AppColors.Primary)
      
      // 季节提示区
      Row() {
        Text(SeasonHints.SpringEmoji)
          .fontSize(AppDimensions.FontXXL)
        Text(SeasonHints.Spring)
          .fontSize(AppDimensions.FontMD)
          .fontColor(AppColors.TextWhite85)
      }
      .padding({ 
        left: AppDimensions.PaddingPage, 
        right: AppDimensions.PaddingPage 
      })
    }
  }
}

Step 3:毛玻璃渐变常量化(符合沉浸光感设计指南)

协议全屏展示区的三层毛玻璃渐变原本是散落的硬编码:

// ❌ 修复前:三处渐变色硬编码,语义不明
.linearGradient({ 
  angle: 180, 
  colors: [
    ['rgba(255,255,255,0.95)', 0.0], 
    ['rgba(245,245,247,0.9)', 0.3], 
    ['rgba(240,240,242,0.85)', 1.0]
  ] 
})

现在通过常量组合:

// ✅ 修复后:Constants 中预先定义三级渐变
// AppConstants.ets 中
static readonly GlassGradientStart: string = 'rgba(255,255,255,0.95)';
static readonly GlassGradientMiddle: string = 'rgba(245,245,247,0.9)';
static readonly GlassGradientEnd: string = 'rgba(240,240,242,0.85)';

// UI 层直接组合
.linearGradient({ 
  angle: 180, 
  colors: [
    [AppColors.GlassGradientStart, 0.0], 
    [AppColors.GlassGradientMiddle, 0.3], 
    [AppColors.GlassGradientEnd, 1.0]
  ] 
})

设计师说"再白一点"? 只需改 AppColors.ets 中的三个值,协议页三层渐变自动同步——这就是轻·透·跨·智中"智"的体现:智能联动,一处修改全域生效。


五、代码增删改清单

文件 操作 新增/修改行数 职责
entry/src/main/ets/constants/AppConstants.ets 新增 +182 五层原子常量体系:色板、尺度、动效、内容、阴影
entry/src/main/ets/constants/ 新增目录 统一存放所有常量配置,后续可扩展 ApiConstants、DBConstants
entry/src/main/ets/pages/Index.ets 修改 -48 / +52 全部 48+ 处硬编码替换为常量引用 + 新增 import
entry/src/main/ets/pages/RecipeDetailPage.ets 修改 -12 / +14 详情页颜色/尺寸常量化
entry/src/main/ets/components/RecommendCard.ets 修改 -8 / +10 推荐卡片样式常量化

净效果:虽然新增了 182 行常量定义文件,但通过消除重复硬编码,全局代码总量净减少约 80 行,且可维护性提升 10 倍以上。


六、血泪避坑总结

现象 真相 解决方案
重构后编译报 Cannot find name 'AppColors' 忘记 import 常量类了 在文件头部加 import { AppColors, AppDimensions, ... } from '../constants/AppConstants'
static readonly 改成普通 static ArkTS 编译器警告"非常量表达式" 必须用 readonly 修饰符,确保编译时常量语义
Color.White 也放进 AppConstants Color.White 是系统内置枚举,放常量里反而绕路 系统内置颜色/枚举直接使用,只常量化自定义设计令牌
常数 0 放进 AppDimensions SpacingNone = 0 毫无意义 零值是默认值,不需要语义化常量
按钮宽度 140 硬要常量化 140 是特定组件场景宽度,不是通用设计令牌 场景专用值保留硬编码,只有复用 3 次以上的值才抽象
改了 AppTexts.Retry 但日志里还是旧文案 日志的 module 标识是独立字符串 TAG = 'AtomicRecommend' 区分"UI 文案令牌"和"日志标识";UI 文案用 AppTexts,日志 tag 用独立常量
毛玻璃颜色改了但阴影没同步 阴影配置独立于颜色常量 将阴影也纳入 AppShadows 常量体系,确保联动更新
折叠屏上间距过大/过小 PaddingPage 固定值未适配断点 使用 Breakpoint 枚举 + 条件返回不同 PaddingPage 值(见下文高级技巧)

进阶技巧:响应式断点适配常量

// 在 AppDimensions 中增加断点适配方法
export class AppDimensions {
  // 基础值
  static readonly PaddingPageBase: number = 20;
  
  // 根据断点返回响应式值
  static getPaddingPage(breakpoint: Breakpoint): number {
    switch (breakpoint) {
      case Breakpoint.SM: return AppDimensions.PaddingPageSM;  // 12
      case Breakpoint.MD: return AppDimensions.PaddingPage;     // 20
      case Breakpoint.LG: return AppDimensions.PaddingPageLG;   // 32
      default: return AppDimensions.PaddingPage;
    }
  }
}

七、设计决策

决策 选择 理由
常量封装形式 static readonly 静态类 编译时内联,零运行时开销;比 enum 支持 string + number + Object 多种类型
颜色语义层级 按用途分类(主色/文本/背景/阴影/透明) 比按"颜色名"分类更贴近设计系统,符合"轻·透·跨·智"中的"智"——智能分类
间距分级策略 XS-SM-MD-LG-XL-XXL-XXXL 七档 覆盖 99% 场景;比 T-shirt Sizing 更精确,符合新空间设计指南的层级节奏
阴影抽象 ShadowConfig 接口 结构化,比三个裸参数更不易出错;支持按卡片层级预设
常量文件拆分 单文件(< 200 行) 当前总量 < 200 行,拆多文件反而增加 import 心智负担;遵循"轻"的理念
毛玻璃透明度值 常量集中管理 设计师调透明层,只改一个文件,全域同步
动效参数 分场景预设(瞬时/快速/标准/入场/退场) 比单一时长更精准,覆盖全场景交互节奏

八、运行验证

验证场景 1:配色全局一致性

  1. AppColors.Primary'#FF6B35' 改为 '#FF4500'
  2. 重新编译运行
  3. 期望结果:Hero 卡片按钮、LoadingProgress、重新加载按钮全部变为新颜色,无遗漏

修改 AppColors.Primary

重新编译

Hero 卡片按钮

LoadingProgress

重新加载按钮

所有使用 Primary 的组件

全部变为新颜色 ✅

验证场景 2:折叠屏/平板自适应

  1. 在 DevEco Studio Previewer 中切换折叠屏/平板形态
  2. 期望结果:所有间距使用 AppDimensions.getPaddingPage(breakpoint) 的容器自动等比填充;ButtonHeight 保持一致

验证场景 3:文案单点修改

  1. AppTexts.ChangeRecipe'换一道' 改为 '不感兴趣'
  2. 期望结果:按钮显示新文案;日志模块标识 TAG 不受影响

验证场景 4:毛玻璃联动更新

  1. 修改 AppColors.GlassGradientStartrgba(255,255,255,0.95) 改为 rgba(255,255,255,0.98)
  2. 期望结果:协议页毛玻璃整体变白一点点,无需改动任何 UI 代码

总体首页效果图

在这里插入图片描述


九、总结与下篇预告

本篇我们基于 HarmonyOS 6.1.0(API 23)和新空间设计指南,为《灵犀厨房》完成了一场从"硬编码地狱"到"原子常量体系"的架构升级。核心要点:

  • 四层原子化:色板层 + 尺度层 + 动效层 + 内容层,层层递进,各自独立
  • 零运行时开销static readonly 编译时内联,与裸值性能完全一致
  • 一处修改全局生效:设计师调色、产品改文案,只改一个文件
  • 语义即文档AppColors.Primary > '#FF6B35'AppDimensions.PaddingPage > 20
  • 架构哲学:常量属于 Infrastructure 层,是"设计令牌",为所有上层提供统一的设计基准
  • 设计理念落地——零运行时开销;——语义透明,自解释;——跨设备/跨层级复用;——智能联动,一处改全域变

AppConstants 速查表

场景 调用
按钮主色 AppColors.Primary
页面边距 AppDimensions.PaddingPage
卡片圆角 AppDimensions.RadiusCard / RadiusXL
入场动画时长 AppAnimations.DurationEnter
重试按钮文案 AppTexts.Retry
春季提示 SeasonHints.Spring + SeasonHints.SpringEmoji
毛玻璃渐变起点 AppColors.GlassGradientStart
轻阴影 AppShadows.CardLight

轻·透·跨·智 设计理念对照表

设计理念 在本篇中的体现 具体实现
轻盈通透 零运行时开销,代码轻量 static readonly 编译时内联,无 GC 压力
空间层次 语义化命名,自解释代码 AppColors.Primary > '#FF6B35'AppDimensions.RadiusXL > 28
跨设备协同 响应式间距常量,多设备统一 AppDimensions.getPaddingPage(breakpoint) 适配 SM/MD/LG
智能感知 设计令牌联动,一处改全域变 修改 AppColors.Primary → 30+ 处组件自动同步

📚 本系列持续更新中,敬请期待,下一篇更精彩。

🔗 专栏入口:《HarmonyOS6.1全场景实战》合集

📦 获取基线版本源码包包括本系列所有代码 + 架构文档 + Flask 后端

如果你觉得这篇文章对你有帮助,请不要吝啬你的点赞 👍、收藏 ⭐ 和评论 💬。你的支持,是我继续输出高质量技术内容的全部动力。
轻·透·跨·智,用心造厨。我们下一篇见!

Logo

讨论HarmonyOS开发技术,专注于API与组件、DevEco Studio、测试、元服务和应用上架分发等。

更多推荐