ArkUI 是 HarmonyOS 的声明式 UI 开发框架,与 ArkTS 深度绑定,让你用写代码的方式"画"界面。它融合了 React 的组件化思想、SwiftUI 的声明式语法,以及 Flutter 的响应式状态管理,但针对鸿蒙系统的渲染管线做了深度优化。

以下是 ArkUI 的完整技术图景:


一、核心架构:声明式 vs 命令式

传统 Android/iOS 开发是命令式(Imperative):你一步步告诉系统"创建一个按钮,设置文字,添加到布局,绑定点击事件"。

ArkUI 采用声明式(Declarative):你描述"界面应该长什么样",框架自动处理渲染细节。

// 命令式思维(伪代码)
TextView tv = new TextView();
tv.setText("Hello");
tv.setTextSize(20);
layout.addView(tv);

// ArkUI 声明式思维
Column() {
  Text("Hello")
    .fontSize(20)
    .fontColor('#333')
}
.padding(20)

优势:代码即设计稿,状态自动驱动 UI 刷新,减少冗余代码 50% 以上。


二、四大核心支柱

1. 装饰器体系(Decorators)

装饰器是 ArkUI 的灵魂,标记组件的角色和数据流:

装饰器 作用 类比
@Entry 页面入口,每个页面必须有且仅有一个 main() 函数
@Component 标记自定义组件结构体 React 的 function Component
@State 组件私有状态,变更触发 UI 刷新 React useState
@Prop 父组件单向传递数据给子组件(只读) Vue props
@Link 父子组件双向同步 Vue v-model
@Provide/@Consume 跨层级数据注入(爷孙通信) React Context
@Watch 监听状态变化 Vue watch
@Builder 声明式 UI 构建函数 渲染函数

2. 内置组件库

ArkUI 提供了丰富的系统组件,按功能分类:

基础组件TextImageButtonTextInputSlider
容器组件(布局核心):

  • Column:垂直排列(flex-direction: column)
  • Row:水平排列(flex-direction: row)
  • Stack:层叠布局(z-index stacking)
  • Flex:弹性布局(完整 flexbox 能力)
  • Grid:网格布局
  • List:高性能长列表(自带复用机制)
  • Tabs:标签页容器

高级组件Web(内嵌网页)、XComponent(OpenGL/C++ 渲染)、VideoCanvas

3. 属性方法链(Modifier)

ArkUI 采用链式调用设置样式,与 SwiftUI 风格一致:

Text("ArkUI")
  .fontSize(20)           // 文字大小
  .fontWeight(FontWeight.Bold)
  .fontColor('#ff6600')
  .maxLines(2)
  .textOverflow({ overflow: TextOverflow.Ellipsis }) // 省略号
  .width('100%')
  .height(50)
  .backgroundColor('#f5f5f5')
  .borderRadius(8)
  .padding({ left: 12, right: 12 }) // 支持 EdgeInsets 对象

响应式单位

  • vp(virtual pixel,虚拟像素,屏幕密度自适应)
  • px(物理像素)
  • %(相对父容器百分比)
  • lpx(大型设备像素,用于平板/2in1 设备)

4. 状态管理(State Management)

ArkUI 的响应式系统基于代理对象(Proxy),当 @State 修饰的变量变更时,框架自动标记脏区域,下一帧刷新。

状态装饰器选择指南

// 场景1:组件内部状态(如计数器)
@Entry
@Component
struct CounterPage {
  @State count: number = 0; // 私有状态
  
  build() {
    Button(`${this.count}`)
      .onClick(() => this.count++) // 自动触发重绘
  }
}

// 场景2:父子单向通信(父→子)
@Component
struct Child {
  @Prop title: string; // 父传子,子组件不可修改
  
  build() {
    Text(this.title)
  }
}

// 场景3:父子双向同步(父子互相影响)
@Component
struct ToggleButton {
  @Link isOn: boolean; // 双向绑定
  
  build() {
    Button(this.isOn ? 'ON' : 'OFF')
      .onClick(() => this.isOn = !this.isOn) // 修改会同步回父组件
  }
}

// 使用 @Link 时必须传递引用($变量)
@Entry
@Component
struct Parent {
  @State parentSwitch: boolean = false;
  
  build() {
    ToggleButton({ isOn: $parentSwitch }) // 注意 $ 符号,表示传递引用
  }
}

三、完整实战:待办事项应用

以下是一个包含增删改查、状态管理的完整 ArkUI 示例:

// 数据模型
interface Todo {
  id: number;
  content: string;
  isDone: boolean;
}

@Entry
@Component
struct TodoListPage {
  @State todoList: Todo[] = [
    { id: 1, content: '学习 ArkTS', isDone: false },
    { id: 2, content: '掌握 ArkUI', isDone: false }
  ];
  @State inputText: string = '';
  
  // 计算属性(通过 getter 实现)
  get unfinishedCount(): number {
    return this.todoList.filter(item => !item.isDone).length;
  }
  
  // 添加任务
  handleAdd() {
    if (this.inputText.trim() === '') return;
    const newTodo: Todo = {
      id: Date.now(),
      content: this.inputText,
      isDone: false
    };
    this.todoList.push(newTodo);
    this.inputText = ''; // 清空输入框
  }
  
  // 删除任务
  handleDelete(index: number) {
    this.todoList.splice(index, 1);
  }
  
  build() {
    Column({ space: 16 }) {
      // 标题统计
      Text(`待办事项 (${this.unfinishedCount} 项未完成)`)
        .fontSize(24)
        .fontWeight(FontWeight.Bold)
        .width('100%')
        .padding(20)
      
      // 输入区域
      Row({ space: 12 }) {
        TextInput({ placeholder: '输入新任务...', text: $$this.inputText })
          .width('80%')
          .height(48)
          .backgroundColor('#f0f0f0')
          .borderRadius(8)
        
        Button('添加')
          .width('20%')
          .height(48)
          .type(ButtonType.Capsule)
          .onClick(() => this.handleAdd())
      }
      .padding({ left: 20, right: 20 })
      .width('100%')
      
      // 列表区域(使用 List 实现高性能滚动)
      List({ space: 12 }) {
        ForEach(this.todoList, (item: Todo, index: number) => {
          ListItem() {
            this.TodoItemBuilder(item, index)
          }
          .swipeAction({ end: this.DeleteButton(index) }) // 侧滑删除
        }, (item: Todo) => item.id.toString()) // 第二个参数是 key,优化 Diff 算法
      }
      .padding(20)
      .layoutWeight(1) // 占据剩余所有空间
      .divider({ strokeWidth: 1, color: '#eeeeee' }) // 分割线
      
    }
    .width('100%')
    .height('100%')
    .backgroundColor('#ffffff')
  }
  
  // @Builder 构建复用的 UI 结构
  @Builder
  TodoItemBuilder(item: Todo, index: number) {
    Row() {
      // 复选框(使用 Toggle)
      Toggle({ type: ToggleType.Checkbox, isOn: item.isDone })
        .selectedColor('#ff6600')
        .onChange((isOn: boolean) => {
          item.isDone = isOn; // 修改数组项会自动触发更新
        })
      
      Text(item.content)
        .fontSize(16)
        .fontColor(item.isDone ? '#999999' : '#333333')
        .decoration({ type: item.isDone ? TextDecorationType.LineThrough : TextDecorationType.None })
        .margin({ left: 12 })
        .layoutWeight(1)
    }
    .width('100%')
    .padding(16)
    .backgroundColor('#f9f9f9')
    .borderRadius(8)
    .gesture(
      TapGesture()
        .onTap(() => {
          // 点击切换完成状态
          item.isDone = !item.isDone;
        })
    )
  }
  
  // 侧滑删除按钮构建器
  @Builder
  DeleteButton(index: number) {
    Button('删除')
      .width(80)
      .height('100%')
      .type(ButtonType.Normal)
      .backgroundColor('#ff4444')
      .fontColor('#ffffff')
      .onClick(() => this.handleDelete(index))
  }
}

四、性能优化技巧

  1. 使用 List 代替 Column:长列表必须用 List,它会自动复用组件实例(类似 iOS 的 Cell Reuse)
  2. @State 粒度控制:避免大对象直接 @State,拆分为独立的小状态
  3. Lazy 加载LazyForEach 配合数据源实现分页加载
  4. 避免大型 build 函数:将复杂 UI 拆分为多个 @Builder 或子组件

五、ArkUI 与主流框架对比

特性 ArkUI React Native Flutter SwiftUI
语言 ArkTS JavaScript/Dart Dart Swift
渲染 自绘引擎(ArkUI-X 跨平台) Native 组件桥接 Skia 自绘 原生渲染
性能 接近原生(无桥接损耗) 有通信损耗 高性能自绘 原生性能
响应式 装饰器驱动 Hooks/Class StatefulWidget Property Wrappers
学习曲线 低(TS 开发者友好) 仅限 iOS

ArkUI 的核心优势在于语言层与渲染层的深度整合:ArkTS 的静态类型信息可以直接用于编译期 UI 布局优化,这是其他框架难以做到的。

需要我详细展开某个特定组件(如动画、手势、自定义绘制)的使用方法吗?

Logo

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

更多推荐