前言
对于刚接触鸿蒙开发的小伙伴来说,Hello World 只是入门第一步。想要真正理解 ArkUI 声明式 UI、响应式状态管理、组件事件交互,计数器绝对是性价比极高的练手项目。
本文基于 HarmonyOS NEXT 系统,使用 DevEco Studio、ArkTS + ArkUI 技术栈,从空白模板出发,一步步实现带加减、归零、文字颜色联动、过渡动画的计数器应用。同时记录开发中遇到的命名冲突踩坑问题,新手可以直接避坑。
一、项目需求与整体目标
本次开发的计数器功能简洁实用,核心需求如下:
在这里插入图片描述

看似简单的功能,却覆盖了鸿蒙 UI 开发 **@State 响应式状态、布局组件、事件绑定、动态样式、动画 ** 五大核心知识点,非常适合入门学习。
二、项目结构解析
打开 DevEco Studio,新建项目,选择 Empty Ability 空白模板、Stage 应用模型,生成标准鸿蒙工程目录,下面对核心目录与文件做解读:
plaintext
项目名/
├── AppScope/ # 应用全局配置目录
│ ├── app.json5 # 应用包名、厂商、版本等基础配置
│ └── resources/ # 全局资源:应用图标、启动页等
├── entry/ # 主业务模块(核心代码全部在这里)
│ ├── build-profile.json5 # 模块构建配置
│ ├── hvigorfile.ts # 编译构建脚本
│ └── src/main/
│ ├── ets/
│ │ ├── entryability/
│ │ │ └── EntryAbility.ets # 应用入口Ability,生命周期管理
│ │ └── pages/
│ │ └── Index.ets # 首页页面组件(本次开发核心文件)
│ ├── module.json5 # 模块声明、页面路由配置
│ └── resources/ # 模块级资源:颜色、字符串、图片、路由
│ ├── base/ # 浅色模式资源
│ └── dark/ # 深色模式资源
├── build-profile.json5 # 工程级全局构建配置
├── oh-package.json5 # 项目依赖配置(类似前端 package.json)
└── hvigor/ # HVigor 构建工具配置目录
2.1 应用入口:EntryAbility.ets
应用启动后,会优先执行 EntryAbility.ets,在 onWindowStageCreate 生命周期函数中加载首页页面,是鸿蒙应用的入口调度文件。

import window from '@ohos.window';
import hilog from '@ohos.hilog';

const DOMAIN = 0xFF00;
const TAG = 'CounterDemo';

export default class EntryAbility extends UIAbility {
  // 窗口创建完成,加载首页页面
  onWindowStageCreate(windowStage: window.WindowStage): void {
    // 加载 pages/Index 页面,无需添加 .ets 后缀
    windowStage.loadContent('pages/Index', (err) => {
      if (err.code) {
        hilog.error(DOMAIN, TAG, '页面加载失败:%{public}s', JSON.stringify(err));
        return;
      }
      hilog.info(DOMAIN, TAG, '页面加载成功');
    });
  }

  // 窗口销毁,可在此做资源释放
  onWindowStageDestroy(): void {

  }
}

关键说明:windowStage.loadContent(‘pages/Index’) 会匹配 ets/pages/Index.ets 文件,文件内被 @Entry 修饰的组件,会渲染为手机可视页面。
2.2 资源分层设计
鸿蒙工程对资源做了清晰分层,职责划分明确:
AppScope/resources:全局应用资源,比如应用桌面图标,作用于整个 App;
entry/src/main/resources:模块级资源,页面配色、文字、路由等业务相关资源统一存放。
分层设计便于项目维护、主题适配与多人协作。
三、方案设计
3.1 响应式状态设计
整个计数器只需要维护一个状态变量:当前计数值 count。
使用鸿蒙专属装饰器 @State 声明为响应式变量:
typescript
运行
@State count: number = 0;
原理:ArkUI 响应式系统会自动监听 @State 变量,一旦数值发生修改,所有依赖该变量的 UI 组件会自动局部刷新,无需手动调用刷新方法。
3.2 页面组件树设计
采用 Column 垂直布局 + Row 水平布局 组合搭建页面,整体结构如下:
plaintext
Column(全屏垂直布局)
├─ Text 标题:计数器
├─ Column(数字展示容器)
│ └─ Text 动态数字(颜色、动画联动)
├─ Row(水平布局)
│ ├─ 减号按钮(红色)
│ └─ 加号按钮(蓝色)
└─ 归零按钮(灰色)
四、完整代码实现
4.1 核心页面 Index.ets(业务主文件)
这是本次开发的核心文件,包含布局、样式、事件、动态颜色、过渡动画全部逻辑:

@Entry
@Component
struct Index {
  // 声明响应式状态:计数器数值,初始值为 0
  @State count: number = 0;

  build() {
    // 根布局:垂直布局,铺满全屏并居中
    Column() {
      // 页面标题
      Text('计数器')
        .fontSize(28)
        .fontWeight(FontWeight.Bold)
        .fontColor('#FF409EFF')
        .margin({ bottom: 40 })

      // 数字展示区域
      Column() {
        Text(this.count.toString())
          .fontSize(72)
          .fontWeight(FontWeight.Bold)
          // 三目运算符实现动态文字颜色
          .fontColor(
            this.count > 0 ? '#FF409EFF'    // 正数:蓝色
            : this.count < 0 ? '#FFFF4757'  // 负数:红色
            : '#FF333333'                   // 零:深灰色
          )
          // 200ms 过渡动画
          .animation({ duration: 200 })
      }
      .width(200)
      .height(200)
      .backgroundColor('#FFF5F5F5')
      .borderRadius(20)
      .justifyContent(FlexAlign.Center)
      .alignItems(HorizontalAlign.Center)
      .margin({ bottom: 40 })

      // 加减按钮行(水平布局)
      Row() {
        // 减号按钮
        Button('−')
          .width(80)
          .height(80)
          .fontSize(36)
          .fontWeight(FontWeight.Bold)
          .backgroundColor('#FFFF4757')
          .borderRadius(40)
          .onClick(() => {
            this.count--;
          })

        // 加号按钮
        Button('+')
          .width(80)
          .height(80)
          .fontSize(36)
          .fontWeight(FontWeight.Bold)
          .backgroundColor('#FF409EFF')
          .borderRadius(40)
          .onClick(() => {
            this.count++;
          })
      }
      .width('100%')
      .justifyContent(FlexAlign.SpaceEvenly)
      .margin({ bottom: 30 })

      // 归零按钮
      Button('归零')
        .width(160)
        .height(48)
        .fontSize(18)
        .fontColor('#FF999999')
        .backgroundColor('#FFF0F0F0')
        .borderRadius(24)
        .onClick(() => {
          this.count = 0;
        })
    }
    .width('100%')
    .height('100%')
    .justifyContent(FlexAlign.Center)
    .alignItems(HorizontalAlign.Center)
    .backgroundColor('#FFFFFFFF')
  }
}

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

五、ArkTS & ArkUI 核心语法详解
5.1 @State 响应式状态
@State 是 ArkUI 最基础、最常用的状态装饰器:
被修饰的变量为响应式变量,数据驱动 UI;
变量修改后,框架自动更新关联组件,无需手动刷新;
作用域仅限当前组件内部使用。
对比传统 Android 命令式 UI:不需要调用 invalidate()、setText() 等方法,数据变 UI 自动变,开发效率大幅提升。
5.2 @Entry 与 @Component 装饰器
@Component:标记当前结构体为自定义 UI 组件,是所有组件的基础;
@Entry:标记当前组件为页面入口,应用启动后自动渲染该组件。
两者组合使用,代表这是一个独立页面。
5.3 链式调用语法
ArkUI 采用声明式链式 API,组件样式、事件、布局全部通过 .属性() 连续编写:
Button(‘+’)
.width(80)
.height(80)
.backgroundColor(‘#FF409EFF’)
.onClick(() => { this.count++ })
优势:UI 结构、样式、逻辑代码集中在一处,不用像传统开发那样「布局 XML + 逻辑代码分离」,可读性和维护性更强。
5.4 三目运算符实现动态样式
文本颜色根据数值正负自动切换,直接在行内使用三目表达式判断,简洁高效:
.fontColor(
this.count > 0 ? ‘#FF409EFF’
: this.count < 0 ? ‘#FFFF4757’
: ‘#FF333333’
)
5.5 原生过渡动画
ArkUI 内置动画能力,仅需一行代码即可实现平滑过渡:
.animation({ duration: 200 })
数值、颜色变化时,会在 200ms 内完成过渡,无需引入额外动画库。
六、开发踩坑:组件命名冲突(新手必看)
6.1 问题现象
初期我将页面结构体命名为 struct Counter,编译后直接报错:
plaintext

  1. Cannot redeclare block-scoped variable ‘Counter’
  2. The struct name cannot contain reserved tag name: ‘Counter’
  3. The struct ‘Counter’ cannot have the same name as the built-in component ‘Counter’
    6.2 问题原因
    Counter 是 ArkUI 框架内置保留组件名,和 Text、Button、Column 一样属于系统关键字。自定义组件名不能和框架内置组件重名,否则触发编译冲突。
    6.3 解决方案
    规避系统保留关键字,修改结构体名称即可:
    diff
  • struct Counter {
  • struct Index {
    修改后重新编译,项目正常运行。
    避坑总结:自定义组件、变量命名,尽量避开 Text/Button/Column/Row/Counter 等系统内置组件名。
    七、运行效果
    点击蓝色「+」按钮:数字递增,文字显示蓝色;
    点击红色「-」按钮:数字递减,负数文字显示红色;
    点击灰色「归零」按钮:数字重置为 0,文字变为深灰色;
    所有数值变化,均带有 200ms 平滑过渡动画。
    八、知识点总结
    8.1 鸿蒙应用分层架构
    本次项目主要使用最上层两大模块:
    plaintext
    UI层(ArkTS + ArkUI) → 页面布局、组件、交互、状态
    Ability层(UIAbility) → 应用生命周期、页面加载调度
    服务层 → 系统能力API调用
    内核层 → 鸿蒙系统内核
    8.2 声明式 UI vs 传统命令式 UI
    在这里插入图片描述

8.3 本次用到核心组件与语法
布局组件:Column 垂直布局、Row 水平布局
基础组件:Text 文本、Button 按钮
核心装饰器:@Entry、@Component、@State
常用能力:onClick 点击事件、animation 过渡动画、三目动态样式
九、项目扩展方向(进阶练习)
基础计数器功能简单,可基于现有代码继续拓展,提升实战能力:
自定义步长:增加 +5、-10 快捷按钮,支持自定义步长;
操作历史记录:使用 List 组件记录每一次加减操作与时间;
数据持久化:借助 Preferences 本地存储,重启应用保留计数值;
动画增强:给数字添加缩放、抖动动画,提升交互质感;
深色模式适配:配置深色模式资源,自动跟随系统主题切换配色。
十、文件清单
整个项目仅需修改一个核心业务文件,模板自带文件无需改动:
entry/src/main/ets/pages/Index.ets:计数器核心代码(主文件)
entry/src/main/ets/entryability/EntryAbility.ets:应用入口(默认模板,无修改)
结语
计数器虽然是入门级项目,但吃透它,就掌握了鸿蒙 ArkUI 开发状态管理、布局、事件、动态样式四大基石。后续开发复杂页面、功能组件,都是在这些基础知识点上延伸。
如果你也是鸿蒙初学者,建议亲手敲一遍代码,结合本文踩坑点规避问题,快速上手鸿蒙应用开发。

Logo

作为“人工智能6S店”的官方数字引擎,为AI开发者与企业提供一个覆盖软硬件全栈、一站式门户。

更多推荐