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

一、前言

HarmonyOS NEXT 已全面去 Android 化,使用纯正的 ArkTS 语言 + Stage 模型开发。本文将手把手带你构建一个「未来技术发展方向」信息展示应用,覆盖 API 24(SDK 6.1.1) 下的核心技术点:页面路由、状态管理、自定义 Builder、条件渲染、网格布局、样式系统等。

开发环境:DevEco Studio NEXT / SDK 6.1.1(24) / Stage Mode / ArkTS


二、项目配置分析

2.1 build-profile.json5 — API 24 核心配置

在根级 build-profile.json5 中,最关键的是 SDK 版本声明:

{
  "app": {
    "products": [
      {
        "name": "default",
        "signingConfig": "default",
        "targetSdkVersion": "6.1.1(24)",
        "compatibleSdkVersion": "6.1.1(24)",
        "runtimeOS": "HarmonyOS"
      }
    ]
  }
}

技术要点:

  • targetSdkVersion: "6.1.1(24)" — 应用以 API 24 为目标运行时,23 之前的旧 API 将不可用
  • compatibleSdkVersion: "6.1.1(24)" — 兼容版本与目标版本一致,表示只适配 NEXT
  • runtimeOS: "HarmonyOS" — 纯鸿蒙运行时,不兼容 Android

2.2 entry/build-profile.json5

{
  "apiType": "stageMode",
  "buildOption": {
    "resOptions": {
      "copyCodeResource": {
        "enable": false
      }
    }
  }
}
  • apiType: "stageMode" — 使用 Stage 模型(API 9+ 推荐),区别于 FA 模型
  • copyCodeResource 控制是否将源码资源拷贝到 HAP 中,调试时可关闭

三、应用入口 — UIAbility 与 Stage 模型

EntryAbility.ets

import { AbilityConstant, UIAbility, Want } from '@kit.AbilityKit';
import { hilog } from '@kit.PerformanceAnalysisKit';
import { window } from '@kit.ArkUI';

export default class EntryAbility extends UIAbility {
  onCreate(want: Want, launchParam: AbilityConstant.LaunchParam): void {
    this.context.getApplicationContext().setColorMode(ConfigurationConstant.ColorMode.COLOR_MODE_NOT_SET);
  }

  onWindowStageCreate(windowStage: window.WindowStage): void {
    windowStage.loadContent('pages/Index', (err) => {
      if (err.code) {
        hilog.error(0x0000, 'testTag', 'Failed to load content: %{public}s', JSON.stringify(err));
      }
    });
  }
}

API 24 关键点:

  • 使用 @kit.AbilityKit 导入(HarmonyOS NEXT 的 Kit 化分包机制)
  • UIAbility 生命周期:onCreateonWindowStageCreateonForegroundonBackgroundonWindowStageDestroyonDestroy
  • windowStage.loadContent('pages/Index', callback) — 加载首页,页面路径需与 main_pages.json 匹配
  • setColorMode(ConfigurationConstant.ColorMode.COLOR_MODE_NOT_SET) — 跟随系统深色/浅色模式

四、页面路由注册 — main_pages.json

{
  "src": [
    "pages/Index",
    "pages/FutureTech"
  ]
}
  • 所有页面必须在此注册,否则运行时无法找到(pushUrl 会报错 100001
  • 路径相对于 ets/ 目录,无需后缀 .ets

五、主页开发 — Index.ets

5.1 完整代码

import { router } from '@kit.ArkUI';

@Entry
@Component
struct Index {
  @State message: string = 'Hello World';

  build() {
    RelativeContainer() {
      Text(this.message)
        .id('HelloWorld')
        .fontSize($r('app.float.page_text_font_size'))
        .fontWeight(FontWeight.Bold)
        .alignRules({
          center: { anchor: '__container__', align: VerticalAlign.Center },
          middle: { anchor: '__container__', align: HorizontalAlign.Center }
        })

      Button('未来技术发展方向 →')
        .fontSize(16)
        .fontWeight(FontWeight.Medium)
        .fontColor('#FFFFFF')
        .backgroundColor('#FF6C6C')
        .borderRadius(24)
        .width(220)
        .height(48)
        .alignRules({
          bottom: { anchor: '__container__', align: VerticalAlign.Bottom },
          middle: { anchor: '__container__', align: HorizontalAlign.Center }
        })
        .margin({ bottom: 60 })
        .shadow({
          radius: 8, color: '#FF6C6C66', offsetX: 0, offsetY: 4
        })
        .onClick(() => {
          router.pushUrl(
            { url: 'pages/FutureTech' },
            router.RouterMode.Single,
            (err) => {
              if (err) {
                console.error('pushUrl failed: ' + JSON.stringify(err));
              }
            }
          );
        })
    }
    .height('100%')
    .width('100%')
  }
}

5.2 技术点详解

@Entry 装饰器
  • 标记该组件为页面的入口组件
  • 一个页面只能有一个 @Entry
  • 配合 main_pages.json 使用
@Component 装饰器
  • 标记该类是一个自定义组件
  • 具备独立的 build 方法
@State 装饰器
@State message: string = 'Hello World';
  • 声明响应式状态变量
  • 当值变化时,自动触发 UI 重新渲染
  • API 24 中,@State 支持的类型更加严格(不可用 any
RelativeContainer 布局
  • 相对布局容器,子组件通过 alignRules 相对锚点定位
  • __container__ 是容器的保留锚点名
  • Stack + 绝对定位更适合响应式布局
router.pushUrl — API 24 新用法
router.pushUrl(
  { url: 'pages/FutureTech' },
  router.RouterMode.Single,
  (err) => { /* 回调 */ }
);
  • 第一个参数:目标页面路由
  • 第二个参数:路由模式 — RouterMode.Single 单实例(同一页面只保留一个栈中实例)、RouterMode.Standard 多实例
  • 第三个参数:可选回调,处理失败场景
  • 旧版无回调的 router.pushUrl({url}) 在 API 24 中已标记为 deprecated
$r() 资源引用
.fontSize($r('app.float.page_text_font_size'))
  • 引用 resources/base/element/float.json 中定义的资源
  • 支持系统资源:$r('sys.string.xxx')
.shadow() 阴影 API
.shadow({
  radius: 8,        // 模糊半径
  color: '#FF6C6C66', // 颜色 + 透明度
  offsetX: 0,       // X 偏移
  offsetY: 4        // Y 偏移
})
  • API 24 支持完整的阴影属性
  • 颜色中可使用 ARGB 格式的 hex 值

六、未来技术页面 — FutureTech.ets(核心)

6.1 数据模型 — ArkTS 接口

interface TechItem {
  title: string
  icon: string
  desc: string
  color: ResourceColor
}

API 24 注意:

  • ArkTS 是静态类型语言,不支持 anyunknown
  • 所有类型必须显式声明
  • ResourceColor 是 ArkUI 框架提供的颜色类型,支持 string hex / Resource 等

6.2 组件结构概览

import { router } from '@kit.ArkUI';

@Entry
@Component
struct FutureTech {
  @State currentIndex: number = 0;

  private techList: TechItem[] = [ /* 8项技术数据 */ ];

  @Builder
  techCard(item: TechItem, index: number) { /* ... */ }

  build() {
    Column() {
      // 1. 顶部标题栏 (Row)
      // 2. 副标题 (Text)
      // 3. 分隔线 (Divider)
      // 4. 选中技术详情卡片 (条件渲染)
      // 5. 技术卡片网格 (Scroll + Column + Row)
      // 6. 底部提示 (Text)
    }
  }
}

6.3 @Builder 装饰器 — 自定义构建函数

@Builder
techCard(item: TechItem, index: number) {
  Column() {
    Text(item.icon).fontSize(48).textAlign(TextAlign.Center)
    Text(item.title).fontSize(18).fontWeight(FontWeight.Bold).fontColor('#FFFFFF')
    Text(item.desc).fontSize(14).fontColor('#E0E0E0').lineHeight(22)
  }
  .width(168)
  .borderRadius(20)
  .backgroundColor(item.color)
  .shadow({ radius: 12, color: item.color + '66', offsetX: 0, offsetY: 6 })
  .onClick(() => { this.currentIndex = index; })
}

@Builder vs @Component 选择:

特性 @Builder @Component
状态管理 无独立状态 可有 @State
复用范围 所在组件内 全局可复用
性能 轻量,无额外节点 有独立生命周期
适用场景 简单 UI 片段 复杂独立组件

这里用 @Builder 是因为卡片只是显示数据+点击回调,不需要独立 @State

6.4 ForEach 列表渲染

Row() {
  ForEach(this.techList.slice(0, 4), (item: TechItem, index: number) => {
    this.techCard(item, index)
  }, (item: TechItem) => item.title)
}

API 24 中 ForEach 的三参数语法:

  1. arr: any[] — 数据源
  2. itemGenerator — 子组件生成函数 (item, index) => void
  3. keyGenerator — 可选,唯一键生成函数 (item, index) => string,用于优化列表 diff

这里手动将 8 项数据分成两行(slice(0,4)slice(4,8)),每行 4 项,通过 FlexAlign.SpaceEvenly 均匀分布。

6.5 条件渲染

if (this.currentIndex >= 0 && this.currentIndex < this.techList.length) {
  Column() {
    // 选中技术的详情展示
  }
  .border({
    width: 1,
    color: this.techList[this.currentIndex].color + '66',
    style: BorderStyle.Solid
  })
}
  • ArkTS 中的 if 条件渲染根据条件动态创建/销毁组件
  • 配合 @State currentIndex,点击卡片时 currentIndex 变化 → UI 自动更新
  • 边界检查 >=0 && < length 防止越界

6.6 router.back() 返回

Text('← 返回')
  .onClick(() => { router.back(); })
  • router.back() 从页面栈中弹出当前页面,回到上一页
  • 对应 pushUrl 的入栈操作

6.7 Divider 分隔线

Divider()
  .width('85%')
  .color('#333333')
  .margin({ bottom: 12 })
  • 水平分隔线,默认宽度自适应
  • 可设置颜色、粗细、圆角等

6.8 Scroll 滚动容器

Scroll() {
  Column() {
    Row() { /* 第一行卡片 */ }
    Row() { /* 第二行卡片 */ }
  }
}
.layoutWeight(1)
  • Scroll 提供垂直滚动,当内容超出屏幕时自动可滚动
  • .layoutWeight(1) 让 Scroll 占据剩余空间(配合 Column 的 flex 布局)

6.9 颜色叠加与毛玻璃效果

.backgroundColor(this.techList[this.currentIndex].color + '33')  // 背景半透明
.border({
  width: 1,
  color: this.techList[this.currentIndex].color + '66',           // 边框半透明
})
  • 通过拼接 hex alpha 通道实现动态半透明效果
  • '33' = 20% 透明度,'66' = 40% 透明度

七、API 24 与旧版 API 关键差异对比

特性 API 9-11 (旧版) API 24 (NEXT)
路由导入 import router from '@ohos.router' import { router } from '@kit.ArkUI'
pushUrl router.pushUrl({url}) router.pushUrl({url}, RouterMode, callback)
类型系统 允许 any 静态类型,禁止 any
Kit 化导入 @ohos/xxx @kit.xxxKit
资源引用 $r('app.string.xxx') 不变,但新增 Resource 类型
SDK 版本 3.x-4.x 6.1.1(24)

八、完整编译构建流程

# 1. 清理构建缓存
hvigorw assembleHap --clean

# 2. 构建 Debug HAP
hvigorw assembleHap --build-mode debug

# 3. 构建 Release HAP
hvigorw assembleHap --build-mode release

编译成功后输出:

BUILD SUCCESSFUL in 23s

生成的 HAP 包位于:

entry/build/default/outputs/default/entry-default-unsigned.hap

九、项目总结

通过这个「未来技术发展方向」应用,我们实践了 HarmonyOS NEXT API 24 下的核心技术:

技术点 应用位置 说明
@Entry/@Component Index.ets, FutureTech.ets 页面入口与组件声明
@State FutureTech.ets 响应式状态管理
@Builder FutureTech.ets 轻量自定义构建函数
router.pushUrl/back Index.ets, FutureTech.ets 页面路由导航
ForEach FutureTech.ets 列表渲染
if 条件渲染 FutureTech.ets 动态显示/隐藏 UI
RelativeContainer Index.ets 相对定位布局
Scroll FutureTech.ets 滚动容器
Divider FutureTech.ets 分隔线
.shadow() Index.ets, FutureTech.ets 阴影效果
main_pages.json resources/base/profile 页面路由注册
UIAbility EntryAbility.ets 应用生命周期
Kit 化导入 全部文件 @kit.xxx 新式导入

十、延伸思考

  1. 数据源改进:当前技术数据是硬编码在组件中的,可从 JSON 文件或网络请求加载,配合 @State 实现动态更新
  2. 动画过渡:可添加 transition + animateTo 实现页面切换动画和卡片浮现动画
  3. 深色模式:通过 @Styles@Extend 定义主题样式,结合 ConfigurationConstant.ColorMode 切换
  4. 性能优化:当卡片数量增多时,可将 ForEach 替换为 LazyForEach 实现懒加载

Logo

AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。

更多推荐