在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

鸿蒙 ArkTS 投屏设备发现列表 DataTable 布局实现详解

一、引言

1.1 背景与项目概述

随着智能家居和万物互联时代的到来,投屏(Screen Casting / Miracast / DLNA)已经成为现代人日常生活中不可或缺的功能。无论是将手机上的视频投射到客厅电视,还是将会议室的 PPT 投放到投影仪,投屏技术都在深刻地改变着我们与数字内容的交互方式。在鸿蒙(HarmonyOS)生态中,投屏能力更是作为分布式架构的核心场景之一,承担着设备间无缝协同的重要使命。

本文基于一个实际的鸿蒙应用开发项目 MyApplication66,深入剖析如何利用鸿蒙 ArkTS 语言及声明式 UI 框架,实现一个功能完备、视觉精美的投屏设备发现列表。该列表以 DataTable(数据表格)为核心交互形态,完整呈现设备名称、在线状态、信号强度以及操作按钮四大维度的信息,适合作为投屏类应用(如 TV Cast、乐播投屏、华为多屏协同等)的设备搜索与连接页面。

1.2 技术栈概览

本项目的技术栈选择充分体现了鸿蒙生态的现代性与先进性:

  • 开发语言:ArkTS(基于 TypeScript 扩展的鸿蒙原生声明式语言)
  • UI 框架:ArkUI(方舟 UI 框架,提供声明式组件化开发范式)
  • 构建工具:Hvigor 6.26.1(鸿蒙新一代轻量级构建系统)
  • 目标设备:鸿蒙手机(Phone)
  • IDE:DevEco Studio(鸿蒙官方集成开发环境)

1.3 文章结构

本文将从需求分析入手,逐步拆解 DataTable 的每一层实现:从数据模型定义、枚举类型设计,到组件树的构建、样式体系规划,再到交互逻辑的串联。每一部分都将配合核心代码片段进行分析,帮助读者建立起鸿蒙 ArkTS 页面开发从 0 到 1 的完整认知。


二、需求分析与设计思路

2.1 投屏设备列表的核心需求

一个典型的投屏设备发现页面,需要满足以下用户场景:

  1. 设备发现:用户打开应用后,自动或手动搜索局域网内可投屏的设备
  2. 信息展示:以列表或表格形式清晰展示每一台设备的名称、类型、当前连接状态和信号质量
  3. 快速筛选:支持按设备名称或 IP 地址搜索,以及按在线/离线状态分类查看
  4. 一键连接:用户点击操作按钮即可发起投屏连接,连接过程有明确的视觉反馈
  5. 状态联动:设备状态变化(在线→使用中、离线恢复在线等)能够实时反映在 UI 上

2.2 DataTable 设计决策

为什么选择 DataTable 而非传统的 Card 列表或 Grid 网格?

布局方案 优点 缺点 适用场景
DataTable 信息密度高、列对齐清晰、便于扫描对比 视觉略显紧凑 设备信息展示、管理后台
Card 列表 视觉宽松、每项独立性强 空间利用率低、对比不便 内容推荐、社交动态
Grid 网格 视觉整齐、适合均等项 列数不灵活、信息承载有限 图标启动器、相册

对于投屏设备列表这一场景,用户需要快速对比多台设备的名称、状态、信号强度三个维度信息,并快速定位到操作按钮。DataTable 的四列布局天然满足这一需求,配合斑马纹(Zebra Striping)的行背景交替设计,阅读效率显著高于其他方案。

2.3 信息架构

页面信息架构由五个层级组成:

  1. 顶层操作区:标题栏(应用标识 + 页面标题)+ 搜索触发按钮
  2. 搜索过滤区:文本输入框 + 清除按钮 + 在线/离线筛选标签
  3. 数据展示区:表头行(列名标识)+ 数据行列表(核心内容)
  4. 状态反馈区:底部统计栏(在线/离线计数)
  5. 全局通知区:Toast 浮层(操作结果反馈)

这种信息架构遵循了 F 型视觉动线(用户从上到下、从左到右扫描内容的自然模式),将最关键的设备信息置于视觉热区。


三、数据模型层实现

3.1 枚举类型设计

良好的枚举设计是类型安全的基础。在投屏设备场景中,我们定义了两个核心枚举:

设备类型枚举 DeviceType
enum DeviceType {
  TV = 'TV',          // 电视
  PROJECTOR = 'PROJECTOR',  // 投影仪
  DONGLE = 'DONGLE',   // 投屏器(如 Chromecast、电视果)
  STREAMER = 'STREAMER', // 流媒体播放器(如 Apple TV、Shield TV)
  AUDIO = 'AUDIO'      // 音响设备(如回音壁、智能音箱)
}

这五类设备覆盖了当前市面上绝大多数投屏终端的形态。值得说明的是,将设备类型作为枚举而非字符串常量有三大好处:

  • 编译期检查:避免了字符串拼写错误导致的数据异常
  • IDE 智能提示:在 DevEco Studio 中输入设备类型时有自动补全
  • 可扩展性:新增设备类型只需在枚举中添加一项,所有 switch-case 分支会触发编译警告,提示开发者同步更新
设备状态枚举 DeviceStatus
enum DeviceStatus {
  ONLINE = 'ONLINE',    // 在线 - 可投屏
  OFFLINE = 'OFFLINE',  // 离线 - 不可连接
  BUSY = 'BUSY'         // 使用中 - 已被其他设备占用
}

三个状态的设计并非随意之举。实际的投屏协议(如 Miracast、AirPlay、DLNA)中,设备通常处于以下状态之一:

  • 在线(Available/Idle):设备空闲,可接受投屏请求
  • 离线(Unreachable/Offline):设备不在线或响应超时
  • 使用中(Busy/Streaming):设备正在处理其他投屏会话

引入 BUSY 状态可以有效避免多个用户同时连接同一台设备导致的冲突。

3.2 数据接口设计

interface DeviceInfo {
  id: number;             // 唯一标识
  name: string;           // 设备名称(如"客厅 小米电视 S Pro")
  type: DeviceType;       // 设备类型枚举
  status: DeviceStatus;   // 当前连接状态
  signalStrength: number; // 信号强度(0-100)
  ip: string;             // 局域网 IP 地址
  lastSeen: string;       // 上次发现时间
}

该接口的设计遵循 SOLID 原则中的单一职责原则——DeviceInfo 只负责描述设备本身的信息,不包含任何 UI 相关的状态(如"是否正在连接")。UI 状态由组件的 @State 变量单独管理,实现了数据层与表现层的清晰分离。

3.3 模拟数据构造

为演示完整的 DataTable 效果,项目内置了 10 台模拟设备:

@State private devices: DeviceInfo[] = [
  { id: 1, name: '客厅 小米电视 S Pro', type: DeviceType.TV, status: DeviceStatus.ONLINE, signalStrength: 95, ... },
  { id: 2, name: '卧室 华为智慧屏 V75', type: DeviceType.TV, status: DeviceStatus.ONLINE, signalStrength: 82, ... },
  { id: 3, name: '会议室 BenQ 投影仪', type: DeviceType.PROJECTOR, status: DeviceStatus.ONLINE, signalStrength: 60, ... },
  // ... 共 10 台
];

模拟数据的设计力求真实:涵盖了不同品牌(小米、华为、三星、索尼、海信等)、不同设备形态(电视、投影仪、投屏器、流媒体盒子、音响)、不同信号强度(从 95 到 0)、不同状态(6 台在线、2 台离线、1 台使用中),以及多样化的 IP 地址段和最后发现时间。


四、UI 组件树的构建

4.1 整体布局结构

ArkUI 的声明式 UI 通过组件嵌套形成组件树。本页面的顶层结构如下:

Stack                      ← 最外层堆叠容器,用于浮动 Toast
  └── Column               ← 主内容垂直布局
        ├── Row            ← 标题栏(图标 + 标题 + 搜索按钮)
        ├── Row            ← 搜索栏(输入框 + 清除按钮)
        ├── Row            ← 设备数量提示
        ├── Row            ← 表格标题行(DataTable Header)
        ├── Divider        ← 表头分隔线
        ├── List           ← 表格数据行(DataTable Body)
        │     └── ListItem × N  ← 每行对应一台设备
        │           └── Column
        │                 ├── Row    ← 设备行内容
        │                 └── Divider ← 行间分隔线
        ├── Column(if)     ← 无结果占位(搜索无匹配时)
        └── Row            ← 底部统计栏
  └── Column(if showToast) ← Toast 通知浮层

这种垂直堆叠的布局方案是移动端列表页面的经典范式,具有以下优点:

  • 主滚动方向单一(垂直):用户操作直觉性强
  • 各区域职责清晰:标题栏、搜索区、数据区、状态区各司其职
  • 条件渲染自然:ArkUI 的 if 条件语句可以直接嵌入组件树,控制占位页和 Toast 的显隐

4.2 标题栏实现

标题栏采用一行三列的布局:左侧是图标和标题文字组合,右侧是功能按钮:

Row() {
  // 左侧图标
  Text('📺')
    .fontSize(28)
  // 标题区域
  Column({ space: 2 }) {
    Text('投屏设备').fontSize(...).fontWeight(FontWeight.Bold)
    Text('发现并连接附近的投屏设备').fontSize(...)
  }
  // 弹性空白
  Blank()
  // 右侧搜索按钮
  Button({ type: ButtonType.Circle }) { Text('🔍').fontSize(20) }
    .width(44).height(44)
    .onClick(() => this.searchDevices())
}

设计要点:

  • Blank() 组件:自动占据剩余空间,将标题和按钮推至两端,实现"两端对齐"效果,比固定 margin 更灵活适配不同屏幕宽度
  • ButtonType.Circle:圆型按钮视觉上更柔和,44×44 的尺寸符合人机交互的最小触控目标(Fitts 定律推荐 ≥ 44pt)
  • Emoji 作为图标:在原型阶段使用 Emoji 作为占位图标,可以快速验证布局而无需导入矢量图标资源

4.3 搜索栏实现

搜索栏包含输入框和条件清除按钮:

Row() {
  TextInput({
    placeholder: '搜索设备名称或 IP 地址...',
    text: this.searchText
  })
  .height(44)
  .backgroundColor($r('app.color.search_background'))
  .borderRadius($r('app.float.search_radius'))
  .onChange((val: string) => { this.searchText = val; })

  // 有输入内容时显示清除按钮
  if (this.searchText !== '') {
    Button({ type: ButtonType.Circle }) {
      Text('✕').fontSize(14)
    }
    .width(28).height(28)
    .onClick(() => { this.searchText = ''; })
  }
}

$r() 是 ArkUI 中引用资源文件的语法。通过将颜色和尺寸值定义在 color.jsonfloat.json 资源文件中,我们实现了设计 Token 的统一管理——当 UI 设计规范更新时,只需修改资源文件,所有引用该 Token 的组件会自动同步更新。

4.4 DataTable 表头实现

表头是 DataTable 区别于普通 List 的核心特征之一:

Row() {
  Text('设备名称').layoutWeight(3)
  Text('状态').layoutWeight(1.2).textAlign(TextAlign.Center)
  Text('信号强度').layoutWeight(1.5).textAlign(TextAlign.Center)
  Text('操作').layoutWeight(1.5).textAlign(TextAlign.Center)
}
.width('100%')
.padding({ left: 20, right: 16, top: 8, bottom: 8 })
.backgroundColor($r('app.color.card_background'))
.borderRadius({ topLeft: 12, topRight: 12 })

layoutWeight 的妙用layoutWeight 是 ArkUI 中实现弹性布局的关键属性,它将 Row 的可用宽度按比例分配给子组件。通过设置 3 : 1.2 : 1.5 : 1.5 的比例,我们实现了:

  • 设备名称列(权重 3)获得最大空间,适合容纳较长的设备名称
  • 状态列(权重 1.2)空间最小,仅为"在线/离线/使用中"几个字
  • 信号强度列(权重 1.5)容纳信号图标和文字
  • 操作列(权重 1.5)容纳按钮

这种比例分配直接反映了各列的信息承载量,避免了固定宽度在不同屏幕尺寸下的适配问题。

4.5 DataTable 数据行实现

数据行是页面中最复杂的组件,需要呈现多个维度的信息:

ListItem() {
  Column() {
    Row() {
      // ---- 设备名称列 ----
      Row({ space: 10 }) {
        Text(this.getDeviceIcon(device.type)).fontSize(24)
        Column({ space: 2 }) {
          Text(device.name).maxLines(1)
            .textOverflow({ overflow: TextOverflow.Ellipsis })
          Row({ space: 6 }) {
            // 设备类型标签
            Text(this.getDeviceTypeLabel(device.type))
              .fontSize(10)
              .border({ width: 0.5, ... })
            // IP 地址
            Text(device.ip).fontSize(10)
          }
        }
      }
      .layoutWeight(3)

      // ---- 状态列 ----
      Row({ space: 4 }) {
        Column().width(8).height(8).borderRadius(4)  // 状态圆点
          .backgroundColor(this.getStatusColor(device.status))
        Text(this.getStatusLabel(device.status))
      }.layoutWeight(1.2)

      // ---- 信号强度列 ----
      Column({ space: 2 }) {
        this.renderSignalIndicator(device.signalStrength)
        Text(this.getSignalLabel(device.signalStrength))
      }.layoutWeight(1.5)

      // ---- 操作列 ----
      Button() { ... }.layoutWeight(1.5)
    }
    // 行间分隔线(最后一行不显示)
    if (index < this.filteredDevices.length - 1) {
      Divider().height(0.5)
    }
  }
}

数据行的设计体现了三个关键原则:

  1. 信息层级清晰:一行中通过字号(16fp 设备名 / 10fp 标签和 IP)、字重(Medium / Normal)、颜色(primary / secondary)三个维度建立视觉层级
  2. 溢出处理:设备名称使用 maxLines(1) + textOverflow(Ellipsis) 保证长名不破坏布局
  3. 分隔线逻辑:最后一行不显示分隔线,避免底部出现多余横线影响整体感

五、信号强度可视化组件

5.1 信号强度柱状图

信号强度的可视化是本页面的一个亮点。不同于简单的文字描述,我们使用 5 根高度递增的柱状条直观展示信号质量:

@Builder
private renderSignalIndicator(strength: number) {
  Row({ space: 3 }) {
    ForEach([1, 2, 3, 4, 5], (bar: number) => {
      Column()
        .width(6)
        .height(4 + bar * 4)          // 高度逐格递增:8,12,16,20,24
        .borderRadius(3)
        .backgroundColor(
          strength === 0
            ? $r('app.color.divider_color')           // 离线:全灰色
            : bar * 20 <= strength                     // 有信号时根据阈值染色
              ? this.getSignalColor(strength)
              : $r('app.color.divider_color')
        )
    })
  }
  .alignItems(VerticalAlign.Bottom)
}

设计思路

  • 5 格 Wi-Fi 风格:借鉴了 Wi-Fi 信号图标的设计语言(1 格弱 → 5 格强),用户无需学习即可理解
  • 高度递进4 + bar * 4 使柱高分别为 8、12、16、20、24 vp,形成自然的斜坡轮廓
  • 三级色体系
    • ≥ 70:绿色(#34C759),对应"强"
    • 40-69:橙色(#FF9500),对应"中"
    • < 40:红色(#FF3B30),对应"弱"
    • 0:全部灰色,对应"无信号"

这种色彩分级的科学依据是人眼对绿/橙/红的感知差异最为敏感,能够在短时间扫视中快速定位信号质量异常的设备。

5.2 状态指示灯

状态指示采用"圆点 + 文字"的组合形式:

Column()
  .width(8).height(8).borderRadius(4)
  .backgroundColor(this.getStatusColor(device.status))

三色圆点规则:

状态 颜色值 色名 代表含义
ONLINE #34C759 绿色 可用、安全、正常
OFFLINE #AEAEB2 灰色 不可用、停用
BUSY #FF9500 橙色 忙碌、等待、占用

颜色选择遵循了通用设计(Universal Design) 原则——即使在不借助文字描述的情况下,用户也能通过颜色感知设备状态,同时配色也考虑了红绿色盲用户的辨识度(绿色 vs 灰色 vs 橙色的明度差异足够大)。


六、交互逻辑实现

6.1 实时搜索过滤

searchText 作为 @State 变量,每输入一个字符都触发 UI 重渲染:

private get filteredDevices(): DeviceInfo[] {
  const text = this.searchText.trim().toLowerCase();
  if (text === '') return this.devices;
  return this.devices.filter(device =>
    device.name.toLowerCase().includes(text) ||
    device.ip.includes(text) ||
    device.type.toLowerCase().includes(text)
  );
}

计算属性(getter)的优势在于:

  • 它是纯函数——只要 searchTextdevices 不变,结果一定相同
  • 它没有副作用——不修改任何状态,仅做计算
  • 它与 ArkUI 的响应式系统自然集成——当 @State 变量改变时,所有引用该 getter 的组件自动重渲染

6.2 连接操作与反馈

连接操作包含完整的用户反馈闭环:

private connectDevice(device: DeviceInfo): void {
  // 步骤 1:前置条件检查
  if (device.status === DeviceStatus.OFFLINE) { ... return; }
  if (device.status === DeviceStatus.BUSY) { ... return; }

  // 步骤 2:设置连接中的设备 ID(触发 UI 显示 Loading)
  this.connectingDeviceId = device.id;

  // 步骤 3:模拟连接(实际项目为网络请求)
  setTimeout(() => {
    this.connectingDeviceId = null;
    this.showToastMessage(`✅ 已成功连接 ${device.name}`);
    // 步骤 4:更新设备状态
    const index = this.devices.findIndex(d => d.id === device.id);
    if (index !== -1) {
      this.devices[index].status = DeviceStatus.BUSY;
    }
  }, 2000);
}

交互反馈闭环

用户点击 [投屏] → 按钮显示 Loading 动画(2s)→ Toast 提示"连接成功"
                                         → 按钮文字变为"使用中"(状态更新)
                                         → 后台自动更新设备列表状态

这个闭环遵循了 Norman 的交互设计七大原则中的即时反馈(Immediate Feedback)——每一次用户操作都有明确的、即时的视觉确认。

6.3 搜索设备模拟

private searchDevices(): void {
  this.isSearching = true;
  this.searchText = '';
  this.showToastMessage('🔄 正在搜索局域网中的投屏设备...');
  setTimeout(() => {
    this.isSearching = false;
    this.showToastMessage(`✅ 搜索完成,发现 ${this.devices.length} 台设备`);
  }, 3000);
}

在真实的投屏应用中,这里会调用 @ohos.net.wifi 或自定义的 UDP 广播协议来发现局域网设备。本文使用 setTimeout 模拟异步操作,在原型阶段足以验证 UI 流程的完整性。

6.4 Toast 通知系统

Toast 组件使用条件渲染和过渡动画:

if (this.showToast) {
  Column() {
    Text(this.toastMessage)
      .fontColor(Color.White)
      .textAlign(TextAlign.Center)
  }
  .backgroundColor(Color.Black).opacity(0.85)
  .borderRadius(12)
  .position({ x: '10%', y: '85%' })
  .width('80%')
  .transition(
    TransitionEffect.opacity(0)
      .combine(TransitionEffect.translate({ y: 50 }))
  )
  .animation({ duration: 300, curve: Curve.Friction })
}
  • TransitionEffect.opacity(0):进入时从完全透明渐变到不透明
  • TransitionEffect.translate({ y: 50 }):进入时从下方 50vp 位置滑入
  • Curve.Friction:摩擦力曲线让动画结束时带有自然刹车的物理感

七、资源与样式体系

7.1 资源文件架构

鸿蒙应用将颜色、尺寸等样式值统一管理在 element 资源目录下:

entry/src/main/resources/
  base/
    element/
      color.json   ← 所有颜色 Token
      float.json   ← 所有尺寸/字号 Token
      string.json  ← 字符串资源
  dark/
    element/
      color.json   ← 深色模式颜色覆盖

7.2 颜色 Token 设计

color.json 中定义了 14 个语义化颜色 Token:

{
  "color": [
    { "name": "primary_blue",       "value": "#007AFF" },
    { "name": "background_light",   "value": "#F5F7FA" },
    { "name": "text_primary",       "value": "#1A1A2E" },
    { "name": "text_secondary",     "value": "#6B7280" },
    { "name": "status_online",      "value": "#34C759" },
    { "name": "status_offline",     "value": "#AEAEB2" },
    { "name": "signal_strong",      "value": "#34C759" },
    { "name": "signal_medium",      "value": "#FF9500" },
    { "name": "signal_weak",        "value": "#FF3B30" },
    // ...
  ]
}

语义化命名的好处是:如果未来品牌色从蓝色(#007AFF)更换为紫色(#5856D6),仅需修改 primary_blue 一处,所有引用该 Token 的按钮、链接、标签颜色自动更新。

7.3 尺寸 Token 设计

{
  "float": [
    { "name": "title_font_size",     "value": "24fp" },
    { "name": "body_font_size",      "value": "16fp" },
    { "name": "small_font_size",     "value": "13fp" },
    { "name": "card_radius",         "value": "16vp" },
    { "name": "button_radius",       "value": "20vp" },
    { "name": "list_item_height",    "value": "72vp" },
    // ...
  ]
}

fp(Font Pixel)是鸿蒙中的字体像素单位,会跟随系统字体缩放设置自适应;vp(Virtual Pixel)是虚拟像素单位,在不同密度屏幕上保持一致的物理尺寸。


八、最佳实践与设计模式

8.1 组件化思想

虽然本页面所有代码位于一个 Index.ets 文件中,但内部采用了组件化的思维:

逻辑单元 实现方式 复用潜力
信号强度指示器 @Builder renderSignalIndicator 高——可在其他页面直接调用
Toast 通知 showToastMessage + if 条件渲染 高——可提取为全局通用组件
设备行渲染 ListItem + ForEach 中——依赖具体数据模型

在实际项目中,这些单元应该进一步拆分为独立组件文件,并使用 @Component 装饰器导出。

8.2 响应式状态管理

页面定义了 5 个 @State 变量,分别管理不同维度的状态:

变量 类型 作用域 触发重渲染的时机
devices DeviceInfo[] 全部设备数据 连接成功后更新状态
searchText string 搜索关键字 每次键盘输入
isSearching boolean 搜索过程 开始/结束搜索
connectingDeviceId number | null 当前连接 点击连接/连接完成
showToast boolean Toast 显隐 显示/3秒后自动隐藏

状态粒度的控制原则:尽可能细粒度。例如,用 connectingDeviceId 代替一个布尔值 isConnecting,这样可以在多台设备同时操作(理论上)时精确控制每一行按钮的状态。

8.3 性能优化

  1. ForEach 的键值生成器(device: DeviceInfo) => device.id.toString(),使用稳定的设备 ID 作为键值,保证列表 diff 更新的效率
  2. 计算属性缓存filteredDevices@State 变量不变时不会重新计算
  3. 条件渲染:Toast 和空状态占位使用 if 条件渲染,不占用组件树节点
  4. layoutWeight 代替固定宽度:避免多次布局计算

九、与同类方案的比较

9.1 Flutter DataTable vs 鸿蒙 DataTable

维度 Flutter DataTable 鸿蒙 ArkUI DataTable 实现
原生组件 提供 DataTableDataColumnDataRow 无原生 DataTable,使用 List + Row 模拟
自定义程度 高,可配置排序、选择等 极高,完全自定义列宽/样式/交互
开发效率 开箱即用 需手动组装
适配灵活性 固定列结构 layoutWeight 弹性分配,天然适配不同屏幕

9.2 SwiftUI List vs 鸿蒙 DataTable

SwiftUI 的 List 同样不提供原生 DataTable,但其 Grid 布局(iOS 16+)可以实现类似效果。鸿蒙 List + Row 的组合在灵活性上与 SwiftUI 相当,但在声明式语法的简洁度上略有差异。


十、总结与展望

10.1 本文要点回顾

本文从零到一实现了鸿蒙 ArkTS 投屏设备 DataTable 页面,覆盖了以下关键技术点:

  1. 数据层:枚举类型(DeviceTypeDeviceStatus)和数据接口(DeviceInfo)的设计
  2. 布局层StackColumnRowListForEach 等 ArkUI 核心组件的组合使用
  3. 样式层:语义化资源 Token 系统、layoutWeight 弹性布局、斑马纹列表
  4. 交互层:实时搜索过滤、连接操作反馈、Toast 通知系统
  5. 可视化:信号强度柱状图、状态指示灯、条件动画过渡

10.2 后续可扩展方向

  • 真实网络发现:接入 @ohos.net.wifi 或 MDNS/DLNA 协议,替代模拟数据
  • 设备排序:按信号强度降序或设备名称升序排列
  • 拖拽排序:用户可自定义设备顺序
  • 上下文菜单:长按设备行弹出更多操作(重命名、收藏、查看详情)
  • 深色模式适配:利用已定义的 dark/element/color.json 自动切换
  • 多语言支持:利用 string.json 进行国际化

10.3 对鸿蒙开发者的建议

  1. 善用资源文件:颜色、尺寸、字符串尽量使用 $r() 引用资源,而非硬编码
  2. 组件拆分的时机:当一个 @Builder 或内部组件超过 30 行代码时,考虑拆分为独立组件
  3. 状态管理为先:开发前先梳理清楚数据流和状态变化图,再动手写 UI
  4. 善用 DevEco Studio:预览器(Previewer)提供了实时布局预览,比反复构建到真机高效得多

附录 A:完整代码

项目完整代码位于 entry/src/main/ets/pages/Index.ets,本文所有代码片段均提取自该文件。

附录 B:资源文件

颜色定义:entry/src/main/resources/base/element/color.json
尺寸定义:entry/src/main/resources/base/element/float.json


Logo

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

更多推荐