目录
工程目录
默认代码
index.ets的默认代码如下:
整体结构
@Entry
@Component
struct Index {
// ...
}
@Entry
: 装饰器,表示这个组件是应用的入口组件(首页)@Component
: 装饰器,表示这个结构体是一个自定义组件struct Index
: 定义了一个名为 Index 的结构体组件
状态变量
@State message: string = 'Hello World';
@State
: 状态装饰器,表示这个变量是组件的状态数据message
: 状态变量名,类型为 string,初始值为 'Hello World'当
message
值变化时,会触发组件的重新渲染
build 方法
build() {
// UI 描述
}
每个组件必须实现 build 方法
用于描述 UI 的结构和布局
RelativeContainer 容器
RelativeContainer() {
// 子组件
}
.height('100%')
.width('100%')
RelativeContainer
: 相对布局容器,子组件可以通过相对定位规则进行布局.height('100%')
: 设置容器高度为父容器的 100%.width('100%')
: 设置容器宽度为父容器的 100%
Text 组件
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 }
})
.onClick(() => {
this.message = 'Welcome';
})
Text(this.message)
: 文本组件,显示 message 状态变量的值.id('HelloWorld')
: 为组件设置 ID,可用于相对布局中的锚点引用.fontSize($r('app.float.page_text_font_size'))
: 设置字体大小,从资源文件中获取值.fontWeight(FontWeight.Bold)
: 设置字体加粗.alignRules()
: 设置相对布局规则center
: 垂直居中(相对于容器)middle
: 水平居中(相对于容器)__container__
: 表示相对于父容器
.onClick()
: 点击事件处理,点击后会将 message 的值改为 'Welcome'
关于$r('app.float.page_text_font_size')
$r()
:资源引用函数,全称是"resource reference"
'app.float.page_text_font_size'
:资源路径标识符
app
:表示应用级资源(固定前缀)
float
:资源类型,表示这是一个浮点数类型的资源
page_text_font_size
:资源名称(自定义的)在我当前的项目中,它所指的路径是:
resources/ └── base/ └── element/ └── float.json
注意:实际路径可能因HarmonyOS版本略有不同,但基本结构一致
ArkTS中常见的数据类型
注意:ArkTS 的设计目标是简化前端开发,因此不强制区分整数和浮点数,ArkTS 没有 int
/long
,因为number
足够灵活
数组
对象
先定义好接口,再用接口约定对象的数据类型(定义对象是的数据类型名就是接口名)。接口名推荐首字母大写。用接口约定对象指的是:对象里面的变量名和对应的类型,要跟接口里定义的一致。
小细节1
接口里定义的属性签名之间不需要用逗号隔开,但是对象里定义的属性之间必须要用逗号隔开
小细节2
在ArkTS中,直接打印对象是看不到对象的具体信息的,只会输出Object,要想看到具体内容,需要打印 对象.属性名 才行
函数
箭头函数
组件基础语法
注意1:build()里要有唯一的容器根组件,由于手机都是自下而上布局的,所以容器根组件一般都是Column
注意2:内容组件如果要设置内容水平居中,可以使用.textAlign(TextAlign.Center),例如
Text('内容')
.textAlign(TextAlign.Center)
通用属性
vp会自动适配不同尺寸的屏幕
在鸿蒙中,满屏尺寸是360或'100%',例如width(360)或width('100%')
文本属性
fp和vp是一样大的,但fp有一个优点:如果用户把手机系统的字体改大或改小,fp可以自适应变化。
图像组件
设置图片宽高有一个特点:只需要设置一个宽或高就行,因为系统会根据图片的原始比例进行等比缩放。
内外边距
如果希望内容跟组件边缘有距离,用内边距padding
如果希望组件之间有距离,用外边距margin
border属性
示例
布局细节
细节1
当给根组件设置宽高百分之百时,系统会预留安全区,如图:
道理也很简单,上面的区域要用于展示手机电池电量,wifi使用等信息;下面的区域要用于展示手机的导航条(用过只能手机的都知道,有三个小按钮)
如果确实想要全部覆盖,可以用下面的属性:
内容较长,这里提供复制粘贴:
.expandSafeArea([SafeAreaType.SYSTEM],[SafeAreaEdge.TOP,SafeAreaEdge.BOTTOM])
细节2-内容的居中与左对齐
当我们第一次写的时候,会疑惑,为什么内容默认是从左边开始的,例如:
接下来,我将一步步刨析。。。。
首先,我们先给根组件加个背景颜色,方便观察:
这时候,我们就发现了,原来并不是内容默认在左边,而是根组件Column只有这么点大(可以看成被内容撑开的大小),而根组件就是默认位于左上角。
那我们现在将跟组件的大小扩展成全屏:
可以发现,文字内容水平居中了,由此我们可以得出结论,组件里的内容,默认是基于组件的大小进行水平居中的。
那如果我们想在根组件全屏的情况下,让里面的内容左对齐,该怎么办呢?只需要给内容组件加一个.width('100%')即可:
为什么加width('100%')就可以左对齐了呢?我是这么理解的:
在加width('100%')之前,内容组件的宽度跟文字宽度一样,并且以根组件的宽度为基准进行水平居中,所以文字在中间:
(两条红线画得不是很标准,能理解意思就行)
在加width('100%')之后,内容组件的宽度大于文字宽度,文字内容会从左到右书写,而内容组件还是以根组件的宽度为基准进行水平居中,此时,看上去,文字内容就左对齐了:
(两条红线画得不是很标准,能理解意思就行)
List组件
ArkTS中的List组件是一个高性能的滚动列表容器,用于展示一系列垂直或水平排列的列表项。它是HarmonyOS应用开发中常用的UI组件之一。
如果想要让滚动条不显示,可以给List组件加上.scrollBar(BarState.Off)
现在预览滚动时,就不会显示滚动条了。
layoutWeight详解
layoutWeight
是 ArkTS 中用于分配剩余空间的重要布局属性,类似于 Android 中的 layout_weight
或 CSS 中的 flex-grow
。它允许组件按比例分配父容器中的剩余空间。
当父容器有剩余空间时,layoutWeight
决定了子组件如何分配这些额外空间:
工作原理:系统会先计算所有子组件的固定尺寸,然后按照各自的
layoutWeight
值比例分配剩余空间默认值:如果不设置,默认值为 0,表示不参与剩余空间分配
适用场景:常用于需要按比例分配空间的布局,如等分屏幕、固定比例布局等
常见问题解答
Q: layoutWeight和width/height同时设置会怎样?
A: 系统会优先满足固定尺寸,然后剩余空间按weight分配。如果空间不足,固定尺寸优先。
Q: 为什么我的layoutWeight没效果?
A: 检查父容器是否有足够剩余空间,以及是否正确设置了尺寸(如.width('100%'))
Q: 负值weight有效吗?
A: 无效,weight必须是≥0的数字
在 ArkTS 中,如果不设置 layoutWeight
(默认值为 0),表示该组件不会参与父容器的剩余空间分配,此时组件的大小行为如下:
1.只占用自身声明的固定尺寸
如果设置了固定宽/高(如 .width(100)
),则严格按该尺寸显示
Text('固定宽度')
.width(100) // 最终宽度就是100px,不参与剩余空间分配
2.未设置固定尺寸时
在
Row
中:宽度由内容撑开(文本长度、图片尺寸等)在
Column
中:高度由内容撑开
if分支语句
条件表达式
条件渲染
循环渲染
状态管理
@Builder
ArkTS 中的 @Builder 详解
@Builder是 ArkTS 中用于构建可复用 UI 组件的装饰器,它允许你将 UI 片段封装成可复用的构建函数。下面我将从多个角度详细解释它的用法和特性。
基本概念
@Builder本质上是一个 UI 构建函数,它可以:
- 封装 UI 片段
- 接受参数进行定制
- 在组件内或全局复用
基本语法
1. 组件内 @Builder
@Component
struct MyComponent {
@Builder myBuilderFunc() {
Column() {
Text('Hello')
.fontSize(20)
Button('Click me')
}
}
build() {
Column() {
this.myBuilderFunc() // 调用Builder
}
}
}
2. 全局 @Builder
@Builder function GlobalBuilder() {
Row() {
Image($r('app.media.icon'))
Text('Global Builder')
}
}
@Entry
@Component
struct MyComponent {
build() {
Column() {
GlobalBuilder() // 调用全局Builder
}
}
}
小细节
1. 全局 Builder(需要
function
关键字)当你想定义一个 全局可复用 的 Builder 时,必须使用
function
关键字特点:
定义在组件外部
可以被项目中任何组件使用
必须加
function
关键字通常放在文件顶层或单独的工具类中
直接通过builderName()调用
2. 组件内 Builder(不需要
function
)当 Builder 是 组件内部专用 时,直接作为组件的成员方法
定义在组件内部
只能被当前组件使用
不需要
function
关键字通过
this.builderName()
调用
核心特性
1. 参数传递
@Builder可以接受参数:
@Builder function ParamBuilder(label: string, color: Color) {
Text(label)
.fontColor(color)
.fontSize(20)
}
@Entry
@Component
struct MyComponent {
build() {
Column() {
ParamBuilder('Warning', Color.Red)
ParamBuilder('Info', Color.Blue)
}
}
}
2. 嵌套调用Builder
可以调用其他 Builder:
@Builder function InnerBuilder() {
Text('Inner Content')
}
@Builder function OuterBuilder() {
Column() {
InnerBuilder()
Divider()
Text('Outer Content')
}
}
3. 与组件方法结合
Builder 中可以调用组件的方法:
@Component
struct MyComponent {
count: number = 0
addCount() {
this.count++
}
@Builder myBuilder() {
Button(`Clicked ${this.count} times`)
.onClick(() => this.addCount())
}
build() {
Column() {
this.myBuilder()
}
}
}
高级用法
1. @BuilderParam
用于组件间传递 Builder:
@Component
struct ChildComponent {
@BuilderParam contentBuilder: () => void
build() {
Column() {
this.contentBuilder()
}
}
}
@Entry
@Component
struct ParentComponent {
@Builder customBuilder() {
Text('Custom Content')
}
build() {
Column() {
ChildComponent({ contentBuilder: this.customBuilder })
}
}
}
2. 条件渲染
Builder 中可以包含逻辑:
@Builder function ConditionalBuilder(show: boolean) {
if (show) {
Text('Visible')
} else {
Text('Hidden').opacity(0.5)
}
}
Stack容器组件
Stack 是 ArkTS 中一种常用的布局容器组件,它允许子组件按照堆叠顺序(z-index)进行层叠排列,类似于 CSS 中的绝对定位布局。
核心特性
层叠布局:
所有子组件默认从同一基准点(左上角)开始布局
后添加的子组件会覆盖在先添加的子组件上方(除非显式设置 z-index)
默认行为:
子组件未设置位置时,默认堆叠在容器左上角
子组件会按照代码书写顺序从底向上层叠(最后一个在最上层)
尺寸特性:
默认撑满父容器(若不设置宽高)
子组件可以通过定位属性自由控制位置
基础语法
Stack({ alignContent: Alignment.BottomEnd }) {
// 子组件会从这里开始层叠
Image($r('app.media.bg'))
.width('100%')
.height('100%')
Text('水印文字')
.fontSize(16)
.margin(10)
}
.width('100%')
.height(200)
.border({ width: 1, color: Color.Gray })
关键属性
子组件可以用下面的属性来控制位置:
常见问题
Q: 如何让某个子组件始终保持在最底层?
A: 为该组件设置 .zIndex(0)
,并为其他组件设置更高的 zIndex
Q: Stack 的子组件能超出容器范围吗?
A: 默认会裁剪超出部分,可通过 .clip(false)
关闭裁剪
Q: 性能考虑
A: 避免在 Stack 中嵌套过多层级,特别是带有动画效果的子组件
Stack 组件非常适合需要创建重叠、悬浮、层叠效果的界面设计,合理使用可以大大增强 UI 的表现力。