HarmonyOS4.0从零开始的开发教程04 初识ArkTS开发语言(下)
HarmonyOS(二) 初识ArkTS开发语言(下)之TypeScript入门
声明式UI基本概念
应用界面是由一个个页面组成,ArkTS是由ArkUI框架提供,用于以声明式开发范式开发界面的语言。
声明式UI构建页面的过程,其实是组合组件的过程,声明式UI的思想,主要体现在两个方面:
- 描述UI的呈现结果,而不关心过程
- 状态驱动视图更新
类似苹果的SwiftUI中通过组合视图View,安卓Jetpack Compose中通过组合@Composable函数,ArkUI作为HarmonyOS应用开发的UI开发框架,其使用ArkTS语言构建自定义组件,通过组合自定义组件完成页面的构建。
自定义组件的组成
ArkTS通过struct声明组件名,并通过@Component和@Entry装饰器,来构成一个自定义组件。
使用@Entry和@Component装饰的自定义组件作为页面的入口,会在页面加载时首先进行渲染。
@Entry
@Component
struct ToDoList {...}
例如ToDoList组件对应如下整个代办页面。
图1 ToDoList待办列表

使用@Component装饰的自定义组件,如ToDoItem这个自定义组件则对应如下内容,作为页面的组成部分。
@Component
struct ToDoItem {...}
图2 ToDoItem

在自定义组件内需要使用build方法来进行UI描述。
@Entry
@Componentstruct ToDoList...build() {...}
}
build方法内可以容纳内置组件和其他自定义组件,如Column和Text都是内置组件,由ArkUI框架提供,ToDoItem为自定义组件,需要开发者使用ArkTS自行声明。
@Entry
@Component
struct ToDoList {...build() {Column(...) {Text(...)...ForEach(...{TodoItem(...)},...)}...}
}
配置属性与布局
自定义组件的组成使用基础组件和容器组件等内置组件进行组合。但有时内置组件的样式并不能满足我们的需求,ArkTS提供了属性方法用于描述界面的样式。属性方法支持以下使用方式:
-
常量传递
例如使用fontSize(50)来配置字体大小。
Text('Hello World').fontSize(50) -
变量传递
在组件内定义了相应的变量后,例如组件内部成员变量size,就可以使用this.size方式使用该变量。
Text('Hello World').fontSize(this.size) -
链式调用
在配置多个属性时,ArkTS提供了链式调用的方式,通过’.'方式连续配置。
Text('Hello World').fontSize(this.size).width(100).height(100) -
表达式传递
属性中还可以传入普通表达式以及三目运算表达式。
Text('Hello World').fontSize(this.size).width(this.count + 100).height(this.count % 2 === 0 ? 100 : 200) -
内置枚举类型
除此之外,ArkTS中还提供了内置枚举类型,如Color,FontWeight等,例如设置fontColor改变字体颜色为红色,并私有fontWeight为加粗。
Text('Hello World').fontSize(this.size).width(this.count + 100).height(this.count % 2 === 0 ? 100 : 200).fontColor(Color.Red).fontWeight(FontWeight.Bold)
对于有多种组件需要进行组合时,容器组件则是描述了这些组件应该如何排列的结果。
ArkUI中的布局容器有很多种,在不同的适用场合选择不同的布局容器实现,ArkTS使用容器组件采用花括号语法,内部放置UI描述。

这里我们将介绍最基础的两个布局——列布局和行布局。
对于如下每一项的布局,两个元素为横向排列,选择Row布局
图3 Row布局

Row() {Image($r('app.media.ic_default'))...Text(this.content) ...
}
...
类似下图所示的布局,整体都是从上往下纵向排列,适用的布局方式是Column列布局。
图4 Column布局

Column() {Text($r('app.string.page_title'))...ForEach(this.totalTasks,(item) => {TodoItem({content:item})},...)}
改变组件状态
实际开发中由于交互,页面的内容可能需要产生变化,以每一个ToDoItem为例,其在完成时的状态与未完成时的展示效果是不一样的。
图5 不同状态的视图

声明式UI的特点就是UI是随数据更改而自动刷新的,我们这里定义了一个类型为boolean的变量isComplete,其被@State装饰后,框架内建立了数据和视图之间的绑定,其值的改变影响UI的显示。
@State isComplete : boolean = false;
图6 @State装饰器的作用

用圆圈和对勾这样两个图片,分别来表示该项是否完成,这部分涉及到内容的切换,需要使用条件渲染if / else语法来进行组件的显示与消失,当判断条件为真时,组件为已完成的状态,反之则为未完成。
if (this.isComplete) {Image($r('app.media.ic_ok')).objectFit(ImageFit.Contain).width($r('app.float.checkbox_width')).height($r('app.float.checkbox_width')).margin($r('app.float.checkbox_margin'))
} else {Image($r('app.media.ic_default')).objectFit(ImageFit.Contain).width($r('app.float.checkbox_width')).height($r('app.float.checkbox_width')).margin($r('app.float.checkbox_margin'))
}
由于两个Image的实现具有大量重复代码,ArkTS提供了@Builder装饰器,来修饰一个函数,快速生成布局内容,从而可以避免重复的UI描述内容。这里使用@Bulider声明了一个labelIcon的函数,参数为url,对应要传给Image的图片路径。
@Builder labelIcon(url) {Image(url).objectFit(ImageFit.Contain).width($r('app.float.checkbox_width')).height($r('app.float.checkbox_width')).margin($r('app.float.checkbox_margin'))
}
使用时只需要使用this关键字访问@Builder装饰的函数名,即可快速创建布局。
if (this.isComplete) {this.labelIcon($r('app.media.ic_ok'))
} else {this.labelIcon($r('app.media.ic_default'))
}
为了让待办项带给用户的体验更符合已完成的效果,给内容的字体也增加了相应的样式变化,这里使用了三目运算符来根据状态变化修改其透明度和文字样式,如opacity是控制透明度,decoration是文字是否有划线。通过isComplete的值来控制其变化。
Text(this.content)....opacity(this.isComplete ? CommonConstants.OPACITY_COMPLETED : CommonConstants.OPACITY_DEFAULT).decoration({ type: this.isComplete ? TextDecorationType.LineThrough : TextDecorationType.None })
最后,为了实现与用户交互的效果,在组件上添加了onClick点击事件,当用户点击该待办项时,数据isComplete的更改就能够触发UI的更新。
@Component
struct ToDoItem {@State isComplete : boolean = false;@Builder labelIcon(icon) {...}...build() {Row() {if (this.isComplete) {this.labelIcon($r('app.media.ic_ok'))} else {this.labelIcon($r('app.media.ic_default'))}... }....onClick(() => {this.isComplete= !this.isComplete;})}
}
循环渲染列表数据
刚刚只是完成了一个ToDoItem组件的开发,当我们有多条待办数据需要显示在页面时,就需要使用到ForEach循环渲染语法。
例如这里我们有五条待办数据需要展示在页面上。
total_Tasks:Array<string> = ['早起晨练','准备早餐','阅读名著','学习ArkTS','看剧放松'
]
ForEach基本使用中,只需要了解要渲染的数据以及要生成的UI内容两个部分,例如这里要渲染的数组为以上的五条待办事项,要渲染的内容是ToDoItem这个自定义组件,也可以是其他内置组件。
图7 ForEach基本使用

ToDoItem这个自定义组件中,每一个ToDoItem要显示的文本参数content需要外部传入,参数传递使用花括号的形式,用content接受数组内的内容项item。
最终完成的代码及其效果如下。
@Entry
@Component
struct ToDoList {...build() {Row() {Column() {Text(...)...ForEach(this.totalTasks,(item) => {TodoItem({content:item})},...)}.width('100%')}.height('100%')}}
图8 ToDoList页面

相关文章:
HarmonyOS4.0从零开始的开发教程04 初识ArkTS开发语言(下)
HarmonyOS(二) 初识ArkTS开发语言(下)之TypeScript入门 声明式UI基本概念 应用界面是由一个个页面组成,ArkTS是由ArkUI框架提供,用于以声明式开发范式开发界面的语言。 声明式UI构建页面的过程ÿ…...
Failed to connect to github.com port 443 after 21055 ms: Timed out
目前自己使用了梯*子还是会报这样的错误,连接不到的github。 查了一下原因: 是因为这个请求没有走代理。 解决方案: 设置 -> 网络和Internet -> 代理 -> 编辑 记住这个IP和端口 使用以下命令: git config --global h…...
Python小技巧:冻结参数,让你的代码变简洁
Python 有一些非常使用的模块, functools 就是其中之一。今天我们来说说其中的 partial 函数, partial 函数看起来平平无奇,如果你经常翻看高手们写的库,会发现很多地方都在使用这函数。 入门 我们从一个小场景开始。 现在我们需…...
如何判断电脑电源质量的好坏?
电脑电源作为电脑的关键部件直接影响到电脑的性能和寿命,因此选择一个好的电源至关重要。那么要如何判断电脑电源的好坏呢?判断的指标都有哪些呢? 1.外观检测 观察电源外观可以初步判断电脑电源的工艺质量和材料质量。外观检测需要检查电源外壳是否坚固࿰…...
装饰器基础知识
一、概述 装饰器是可调用的对象,其参数是另一个函数(被装饰的函数)。装饰器可能会处理被装饰的函数,然后把它返回,或者将其替换成另一个函数或可调用对象。 装饰器的一大特性是,能把被装饰的函数替换成其他…...
轻量封装WebGPU渲染系统示例<42>- vsm阴影实现过程(源码)
前向实时渲染vsm阴影实现的主要步骤: 1. 编码深度数据,存到一个rtt中。 2. 纵向和横向执行遮挡信息blur filter sampling, 存到对应的rtt中。 3. 将上一步的结果(rtt)应用到可接收阴影的材质中。 具体代码情况文章最后附上的实现源码。 当前示例源码github地址: …...
[Electron] 将应用日志文件输出
日志文件输出可以使用 electron-log 模块。 electron-log 是一个用于 Electron 应用程序的日志记录库。它提供了一种简单且方便的方式来在 Electron 应用中记录日志信息,并支持将日志输出到文件、控制台和其他自定义目标。 以下是 electron-log 的一些主要特点…...
特性【C#】
C#特性是一种用于在编译时向程序元素添加声明性信息的语言结构。 下面是C#特性的使用方法: 1.使用系统提供的特性: 可以使用系统提供的特性来标记类、方法、属性等,以便在编译时进行验证或者提供其他信息。例如,可以使用Obsole…...
理解SpringIOC和DI第一课(Spring的特点),IOC对应五大注解,ApplicationContext vs BeanFactory
Spring是一个包含众多工具等Ioc容器 对象这个词在Spring范围内,称为bean Spring两大核心思想 1.IOC (IOC是控制反转,意思是控制权反转-控制权(正常是谁用这个对象,谁去创建,)-控制对象的控制权…...
【微服务】分布式限流如何实现
Sentinel 是一款阿里巴巴开源的分布式系统级流量控制组件,它提供了流量的自适应控制、熔断降级、系统负载保护等功能。下面是使用 Sentinel 实现分布式限流方案的基本步骤: 引入 Sentinel 依赖:首先在你的 Java 项目中引入 Sentinel 的相关依…...
【S32K3环境搭建】-0.3-S32DS安装实时驱动RTD(Real-Time Driver)
目录 1 什么是“实时驱动RTD(Real-Time Driver)” 2 安装“实时驱动RTD(Real-Time Driver)” 2.1 方法一:通过S32DS Extensions and Updates安装“实时驱动RTD(Real-Time Driver)” 2.2 方法二:通过Install New Software…安装“实时驱动RTD(Real-Ti…...
软件设计之适配器模式
类模式 我们知道插座的电压为交流电220V,而日常电器使用的是直流电且电压会较小,比如手机充电会通过插头适配器达到额定的输入电流。下面我们实现这个案例:将220V电压转化为5V的电压。 package Adapter.Class;public class Adapter extends …...
虚拟化逻辑架构:OVS 交换机与端口管理
目录 一、实验 1.OVS 交换机管理 2.OVS端口管理 二、问题 1.KVM下的br0和virbr0有何区别 2.OVS 虚拟交换机 与接口如何实现关联的创建和删除 3.两个ovs之间如何进行流量交互 4.虚拟网络如何和物理网络互联 一、实验 1.OVS 交换机管理 (1)查看网…...
【springboot】idea项目启动端口被占用
问题 idea本地启动springboot项目端口老是被占用 解决 关闭被占用的端口进程 步骤: 1. winR打开程序框 2. 查出被占用端口的进程id netstat -ano | finderstr 端口号 例如 netstat -ano | finderstr 81013.杀死进程 taskkill /pid 进程id -t -f 例如 taskkill /pid 2…...
linux环境下编译安装OpenCV For Java(CentOS 7)
最近在业余时间学习了一些有关图像处理的代码,但是只能本地处理,满足不了将来开放远程服务的需求。 因此,查找并参考了一些资料,成功在centos7环境安装上了opencv 460。 下面上具体安装步骤,希望能帮到有需要的同学。 …...
健康学习到 150 岁:人体系统调优不完全指南 | 开源日报 No.93
jesseduffield/lazygit Stars: 40.0k License: MIT lazygit,一个用 Go 语言编写的简单终端UI工具,可以执行 Git 命令。 该项目旨在让使用者更加方便地使用 Git,并提供了以下功能: 可视化操作:用户可以通过图形界面进…...
C++ Easyx 三子棋
目录 思路 框架编辑 读取操作 数据操作 绘制画面 游戏的数据结构 用二维数组来模拟棋盘格 赢的情况 平局情况 Code 代码细节部分 (1)初始化棋盘格 (2) 初始化棋子类型编辑 事件处理部分 落子 框架内代码的完善 数据处…...
[NAND Flash 2.1] NAND Flash 闪存改变了现代生活
依公知及经验整理,原创保护,禁止转载。 专栏 《深入理解NAND Flash》 <<<< 返回总目录 <<<< 1989年NAND闪存面世了,它曾经且正在改变了我们的日常生活。 NAND 闪存发明之所以伟大,是因为,…...
2015年五一杯数学建模B题空气污染问题研究解题全过程文档及程序
2015年五一杯数学建模 B题 空气污染问题研究 原题再现 近十年来,我国 GDP 持续快速增长,但经济增长模式相对传统落后,对生态平衡和自然环境造成一定的破坏,空气污染的弊病日益突出,特别是日益加重的雾霾天气已经干扰…...
java面试题,上楼梯有多少种方式
java面试题,上楼梯有多少种方式 题目:一个小孩上一个N级台阶的楼梯,他可以一次走1阶、2阶或3阶,那么走完N阶有多少种方式。 很自然的想法是使用递归: public class Test04 { public static int countWays(int n) {…...
Wan2.1-umt5开发环境搭建:IDEA集成与调试技巧详解
Wan2.1-umt5开发环境搭建:IDEA集成与调试技巧详解 如果你是一名Java开发者,最近开始接触Wan2.1-umt5这类模型,可能会觉得有点无从下手。模型本身是用Python写的,各种脚本和命令行操作,跟咱们熟悉的Java开发环境完全是…...
ANIMATEDIFF PRO效果展示:森林晨雾中飘落树叶+光线穿透动态GIF集
ANIMATEDIFF PRO效果展示:森林晨雾中飘落树叶光线穿透动态GIF集 1. 引言:当AI遇见电影级动态美学 想象一下,你脑海中有一个绝美的画面:清晨的森林,薄雾缭绕,阳光透过层层叠叠的树叶,形成一道道…...
【Python 教程】如何将 JSON 数据转换为 Excel 工作表
pagehelper整合 引入依赖com.github.pagehelperpagehelper-spring-boot-starter2.1.0compile编写代码 GetMapping("/list/{pageNo}") public PageInfo findAll(PathVariable int pageNo) {// 设置当前页码和每页显示的条数PageHelper.startPage(pageNo, 10);// 查询数…...
重新定义开源RTS体验:Beyond All Reason深度技术解析
重新定义开源RTS体验:Beyond All Reason深度技术解析 【免费下载链接】Beyond-All-Reason www.beyondallreason.info 项目地址: https://gitcode.com/gh_mirrors/be/Beyond-All-Reason Beyond All Reason是一款基于Spring引擎开发的开源实时战略游戏…...
7个维度解锁洛雪音乐音源:从新手到专家的全方位指南
7个维度解锁洛雪音乐音源:从新手到专家的全方位指南 【免费下载链接】lxmusic- lxmusic(洛雪音乐)全网最新最全音源 项目地址: https://gitcode.com/gh_mirrors/lx/lxmusic- 洛雪音乐音源作为GitHub加速计划的重要组成,是一款专注于音乐资源聚合的…...
如何在浏览器中免安装使用微信?这个开源插件给你答案!
如何在浏览器中免安装使用微信?这个开源插件给你答案! 【免费下载链接】wechat-need-web 让微信网页版可用 / Allow the use of WeChat via webpage access 项目地址: https://gitcode.com/gh_mirrors/we/wechat-need-web 你是否曾经遇到过这样的…...
AIGlasses_for_navigation网络通信基础:TCP/IP协议栈与实时数据传输优化
AIGlasses_for_navigation网络通信基础:TCP/IP协议栈与实时数据传输优化 最近和几个做智能眼镜导航项目的朋友聊天,他们都在为一个问题头疼:眼镜端看到的导航画面,有时候会卡顿一下,或者指令响应慢半拍。这听起来是小…...
Homebrew安装后zsh补全报权限警告?深入聊聊macOS下/usr/local的目录权限管理
Homebrew安装后zsh补全报权限警告?深入聊聊macOS下/usr/local的目录权限管理 每次打开终端都看到那个烦人的zsh警告:"insecure directories, run compaudit for list",确实让人头疼。但这个问题背后隐藏着macOS系统权限管理的深层逻…...
Ubuntu 20.04 LTS静态IP配置避坑指南:从NetworkManager到netplan的完整流程
Ubuntu 20.04 LTS静态IP配置深度解析:从NetworkManager到netplan的无缝迁移 在服务器管理和开发环境中,稳定的网络连接是基础中的基础。Ubuntu 20.04 LTS作为长期支持版本,其网络配置方式从传统的NetworkManager逐渐转向了更现代的netplan工具…...
别再只盯着YOLOv5了!聊聊FPN、PANet这些‘特征融合’老将如何帮你搞定小目标检测
小目标检测实战:FPN与PANet如何突破YOLO系列的性能瓶颈 在工业质检项目中,我们团队曾遇到一个典型问题:使用YOLOv5s模型检测电路板元件时,虽然大尺寸的电容电阻识别准确率超过95%,但0402封装的微型贴片元件(…...
