鸿蒙ArkUI采用声明式布局体系,所有页面都遵循「一个根布局,根布局内可嵌套多层子布局」的规则,下面为你逐个讲解常用布局:
ColumnColumn是最常用的垂直排列容器,所有子元素会沿着垂直方向从上到下依次排列,可以通过属性控制对齐方式和元素间距,非常适合做页面的根容器、表单列表排列。属性:
spacejustifyContentStart(顶部对齐,默认)、Center(居中对齐)、End(底部对齐)、SpaceBetween(均匀分布,首尾不留空)、SpaceAround(均匀分布,首尾留半空)alignItemsStart(左对齐)、Center(居中对齐)、End(右对齐)代码示例:
@Entry@Componentstruct VerticalDemo {build() {Column({ space: 10 }) {Text("第一条内容") .fontSize(20) .width('100%') .backgroundColor('#f0f0f0')Text("第二条内容") .fontSize(20) .width('100%') .backgroundColor('#e0e0e0')Text("第三条内容") .fontSize(20) .width('100%') .backgroundColor('#f0f0f0') } .width('100%') .padding(15) .alignItems(HorizontalAlign.Start) }}
垂直布局示例代码运行效果图:

RowRow是水平排列容器,所有子元素会沿着水平方向从左到右依次排列,适合做顶部导航栏、按钮组、横向表单项目排列。
属性:
spacejustifyContentColumn一致alignItemsTop(顶部对齐)、Center(居中对齐)、Bottom(底部对齐)代码示例:
@Entry@Componentstruct HorizontalDemo {build() {Row({ space: 12 }) { // 水平排列,元素间距12vpButton("首页")Button("分类")Button("我的") } .width('100%') .height(50) .backgroundColor('#fff') .justifyContent(FlexAlign.Center) // 水平居中排列 .alignItems(VerticalAlign.Center) // 垂直居中对齐 }}
水平布局对齐方式示例效果图

RelativeContainer相对布局是自由度极高的布局方式,允许子组件基于父容器,或者其他子组件设置对齐规则来确定位置,非常适合实现复杂的不规则页面布局,是鸿蒙开发中处理复杂界面的核心布局。
用法:
idalignRules配置对齐规则:可以设置left(左边缘对齐)、right(右边缘对齐)、top(上边缘对齐)、bottom(下边缘对齐),规则内容为anchor: '组件id'表示对齐到对应组件的对应边缘代码示例:
@Entry@Componentstruct RelativeDemo {build() {RelativeContainer() {// 床1:靠左上角Text("1号床") .size({width: 100, height: 100}) .backgroundColor(Color.Pink) .alignRules({left: {anchor: '__container__', align: RelativeAlign.Left},top: {anchor: '__container__', align: RelativeAlign.Top} }) .id("bed1")// 床2:床1的右侧,顶部和床1对齐Text("2号床") .size({width: 100, height: 100}) .backgroundColor(Color.Blue) .alignRules({left: {anchor: 'bed1', align: RelativeAlign.Right},top: {anchor: 'bed1', align: RelativeAlign.Top} }) .id("bed2") } .size({width: '100%', height: 400}) .padding(10) }}
(__container__代表根容器自身,代表对齐到父容器)
相对布局宿舍床位示例运行效果图

StackStack是层叠容器,子组件会按照代码顺序依次堆叠,后面写的组件会覆盖在前面的组件上方,非常适合实现「图片上飘文字」、「卡片角标」、「悬浮按钮」这类需要叠加元素的场景。
属性:
alignContentposition,做绝对定位代码示例:
@Entry@Componentstruct StackDemo {build() {Stack({ alignContent: Alignment.BottomEnd }) {// 底层:卡片内容Column() {Text("课程卡片") .fontSize(18) } .width('90%') .height(200) .backgroundColor(Color.White) .borderRadius(12)// 上层:悬浮按钮,叠在右下角Button("+") .width(40) .height(40) .borderRadius(20) .margin({ right: 10, bottom: 10 }) } .width('100%') .height(250) .padding(10) }}
层叠布局悬浮按钮示例运行效果图

FlexFlex是流式弹性布局,相比Row/Column更灵活,支持设置换行,自动分配子元素空间,非常适合实现标签流、不规则网格、响应式排列这类场景。
属性:
directionwrapFlexWrap.Wrap代表自动换行,超出主轴宽度自动切到下一行,实现流式布局justifyContentalignItems:和Row/Column类似,控制主轴和交叉轴的对齐方式代码示例:
@Entry@Componentstruct FlexDemo {build() {Flex({ wrap: FlexWrap.Wrap, space: { mainAxis: 10, crossAxis: 10 } }) {// 多个标签自动换行Text("鸿蒙开发") .padding({ left: 12, right: 12, top: 6, bottom: 6 }) .backgroundColor('#e0f0ff') .borderRadius(16)Text("ArkTS") .padding({ left: 12, right: 12, top: 6, bottom: 6 }) .backgroundColor('#e0f0ff') .borderRadius(16)Text("布局学习") .padding({ left: 12, right: 12, top: 6, bottom: 6 }) .backgroundColor('#e0f0ff') .borderRadius(16)// 更多标签... } .padding(15) }}
弹性布局标签按钮流式排列效果图

布局是页面的骨架,组件就是页面的血肉,常用基础组件如下:
SwiperSwiper是鸿蒙提供的原生轮播组件,专门用来做首页banner轮播、图片漫游等需要滑动切换的场景,支持自动播放、循环滚动、自定义指示器。属性:
autoPlayloopintervalindicator代码示例:
@Entry@Componentstruct SwiperDemo {build() {Swiper() {Image($r('app.media.banner1')) // 第一张轮播图 .width('100%') .height(200) .objectFit(ImageFit.Cover)Image($r('app.media.banner2')) // 第二张轮播图 .width('100%') .height(200) .objectFit(ImageFit.Cover)Image($r('app.media.banner3')) // 第三张轮播图 .width('100%') .height(200) .objectFit(ImageFit.Cover) } .autoPlay(true) .loop(true) .interval(3000) .indicator(true) .width('100%') .height(200) .margin(15) }}
Swiper图片轮播示例运行效果图(需要准备对应banner图片资源)

VideoVideo是原生视频播放组件,支持播放本地、网络视频,自带控制栏,也可以通过控制器自定义控制播放、暂停、进度跳转。属性:
src$rawfile('视频文件名.mp4')读取资源文件,网络视频直接填urlcontrollerVideoController对象来控制视频播放代码示例:
import video from'@ohos.multimedia.video';@Entry@Componentstruct VideoDemo {privatecontroller: video.VideoController = new video.VideoController();build() {Column() {Video({src: $rawfile('1.mp4'),controller: this.controller }) .width('100%') .height(250) .controls(true) // 显示默认控制栏 } }}
Video视频播放界面运行效果图

ImageImage用来展示本地或网络图片,鸿蒙中读取本地资源一般通过$r('app.media.图片名')的语法引用。
属性:
objectFitImageFit.Cover按比例铺满容器、ImageFit.Contain完整显示整个图片代码示例:
// 加载本地资源图片Image($r('app.media.avatar')) .width(80) .height(80) .borderRadius(40) // 设置圆角实现圆形头像 .objectFit(ImageFit.Cover)// 加载网络图片Image('https://example.com/demo.jpg') .width('100%') .height(200)
个人信息页图片展示效果图

Tabs + TabContentTabs是底部/顶部选项卡容器,搭配TabContent实现多页面切换,是很多App首页框架的标配。
属性:
barPositionBarPosition.End放在底部,BarPosition.Start放在顶部TabContent对应一个选项卡页面,通过tabBar设置选项卡标题和样式代码示例:
@Entry@Componentstruct TabsDemo {@StatecurrentIndex: number = 0;build() {Tabs({ barPosition: BarPosition.End }) {TabContent() {// 首页内容写在这里Text("首页内容") }.tabBar("首页")TabContent() {// 推荐内容写在这里Text("推荐内容") }.tabBar("推荐")TabContent() {// 我的内容写在这里Text("我的内容") }.tabBar("我的") } .width('100%') .height('100%') }}
多标签App框架运行效果图

Text + TextInputTextTextInput属性:
placeholdertypeInputType.Password代表密码输入,会隐藏内容onChange代码示例:
@Entry@Componentstruct FormDemo {@Stateusername: string = '';@Statepassword: string = '';build() {Column({ space: 15 }) {Text("账号") .fontSize(16) .width('100%')TextInput({ placeholder: '请输入账号', text: this.username }) .width('100%') .height(40) .onChange((val) => {this.username = val; // 输入内容变化同步到状态变量 })Text("密码") .fontSize(16) .width('100%')TextInput({ placeholder: '请输入密码', text: this.password }) .width('100%') .height(40) .type(InputType.Password) .onChange((val) => {this.password = val; }) } .padding(15) }}
登录注册表单输入框运行效果图

Button按钮是最核心的交互组件,用户点击后触发对应的操作,支持设置按钮样式、圆角、背景色。
代码示例:
// 普通按钮Button("登录") .width('90%') .height(45) .fontSize(16) .backgroundColor('#007dff') .borderRadius(8) .onClick(() => {// 点击后执行的逻辑写在这里console.log("用户点击了登录按钮"); })
多种样式按钮示例运行效果图

Radio 单选框用于多选一的场景,同一个分组内的单选框只能选中一个,所有单选框必须设置同一个group分组名。
每个Radio绑定一个value,通过onChange回调判断是否选中当前选项。
代码示例:
@Entry@Componentstruct RadioDemo {@Stategender: string = 'male';build() {Row({ space: 30 }) {Text("性别:")Row({ space: 8 }) {Radio({ value: 'male', group: 'gender' }) .checked(this.gender === 'male') .onChange(() => {this.gender = 'male' })Text("男") }Row({ space: 8 }) {Radio({ value: 'female', group: 'gender' }) .checked(this.gender === 'female') .onChange(() => {this.gender = 'female' })Text("女") } } .alignItems(VerticalAlign.Center) }}
表单单选框选项运行效果图

ToggleToggle是切换类组件,分为两种类型:ToggleType.Switch滑动开关(用于开/关功能切换)、ToggleType.Checkbox复选框(用于多选场景),支持状态联动,切换状态时可以自动更新UI。
isOnonChange代码示例:
@Entry@Componentstruct ToggleDemo {@Stateopen: boolean = false;build() {Column({ space: 15 }) {Text(this.open ? "夜间模式已开启" : "夜间模式已关闭") .fontSize(18) .fontColor(this.open ? Color.White : Color.Black)Toggle({ type: ToggleType.Switch, isOn: this.open }) .onChange((value: boolean) => {this.open = value; // 状态变化同步到变量,自动刷新UI }) } .width('100%') .height('100%') .backgroundColor(this.open ? Color.Black : Color.White) .padding(15) }}
Toggle开关联动背景色示例运行效果图

除了布局和组件,还需要掌握这几个核心开发知识,才能实现完整可交互的功能:
@State 状态管理@State是ArkTS最基础的状态装饰器,被@State装饰的变量是响应式状态变量——当变量值发生改变时,所有用到这个变量的UI会自动刷新,这是ArkUI实现交互的核心基础。
@Component装饰的组件内定义string/number/boolean等)和对象、数组代码示例:
@Entry@Componentstruct StateDemo {// 定义响应式状态变量@StateinputContent: string = "";@StateswitchStatus: boolean = false;build() {Column({ space: 20 }) {// 状态变量直接用在UI中,变量变化UI自动变Text(`输入内容:${this.inputContent}`) .fontSize(18)TextInput({ placeholder: "请输入内容", text: this.inputContent }) .onChange((val) => {// 修改状态变量,UI自动刷新this.inputContent = val; })Toggle({ type: ToggleType.Switch, isOn: this.switchStatus }) .onChange((val) => {this.switchStatus = val; }) } .padding(15) }}
在登录、注册、计算器这些需要动态更新界面的场景,都需要用@State来管理数据,这是ArkTS声明式开发最核心的思想——数据驱动视图。
AlertDialogAlertDialog是系统原生弹窗,一般用来给用户展示提示信息,或者让用户做确认操作,在操作完成(比如登录成功/失败、注册完成)后非常常用。
代码示例:
// 在按钮点击事件中弹出弹窗Button("登录") .onClick(() => {if (this.username === "admin" && this.password === "123456") {// 登录成功弹窗AlertDialog.show({title: "登录成功",message: "欢迎回来,admin",confirm: {value: "确定",action: () => {console.log("用户点击确认"); } } }) } else {// 登录失败弹窗AlertDialog.show({title: "登录失败",message: "账号或密码错误,请重新输入",confirm: {value: "确定",action: () => {} } }) } })
登录结果弹窗运行效果图

router路由用来实现多页面跳转和参数传递,一个应用一般会包含多个页面,通过路由管理页面的跳转、回退和数据传递。
import router from '@ohos.router';router.pushUrl({ url: 'pages/页面名', params: { 参数key: 参数值 } })onPageShow生命周期中,通过router.getParams()获取参数main_pages.json中注册,否则无法跳转代码示例:
// 1. 注册页点击提交后,跳转登录页并传递注册信息import router from'@ohos.router';@Entry@Componentstruct RegisterPage {@Stateusername: string = "";@Statepassword: string = "";build() {// 省略表单代码...Button("注册并登录") .onClick(() => { router.pushUrl({url: "pages/LoginPage",params: {account: this.username,pwd: this.password } }) }) }}
代码示例:
// 2. 登录页接收注册页传递的参数import router from'@ohos.router';@Entry@Componentstruct LoginPage {@Stateaccount: string = "";onPageShow() {// 页面显示时获取传递过来的参数const params = router.getParams() asany;if (params.account) {this.account = params.account; } }build() {// 省略登录表单代码... }}
注意: 必须在这里把所有页面路径添加到src数组中,路由才能正常跳转,例如:
json文件示例
{"src":["pages/Index","pages/RegisterPage","pages/LoginPage"]}
页面跳转流程图


事件是用户和应用交互的桥梁,ArkTS中最常用的两类事件是输入变化事件和点击事件:
onChange(() => { }) 变化事件 当组件的值发生改变时触发,一般用于输入框输入内容变化、开关状态切换、滑块值变化这类场景,可以拿到最新的值,同步给@State变量,让UI自动更新。
代码示例:
// 场景1:TextInput输入内容变化@Stateusername: string = '';TextInput({text: this.username}) .onChange((newValue: string) => {// 输入内容改变,更新状态变量,UI自动刷新显示最新内容this.username = newValue;console.log("当前输入内容:" + this.username); })// 场景2:Toggle状态变化@StateswitchOpen: boolean = false;Toggle({type: ToggleType.Switch, isOn: this.switchOpen}) .onChange((newStatus: boolean) => {// 开关状态改变,更新状态变量,UI中依赖这个状态的部分自动刷新this.switchOpen = newStatus; })

onClick(() => { }) 点击事件当用户点击组件时触发,是最常用的交互事件,几乎所有可点击的元素(按钮、文本、图片、卡片等)都可以绑定点击事件,点击后执行对应的业务逻辑:比如提交表单、跳转页面、计算结果、弹出弹窗等。
代码示例:
// 场景1:按钮点击提交登录Button("登录") .onClick(() => {// 点击后做验证、弹窗、跳转等逻辑if (this.username.length > 0 && this.password.length > 0) {this.doLogin(); } else {AlertDialog.show({title: "提示", message: "请输入账号密码", confirm: {value: "确定", action: () => {}}}) } })// 场景2:文本点击跳转注册页Text("没有账号?去注册") .fontColor('#007dff') .onClick(() => { router.pushUrl({url: "pages/RegisterPage"}); })
图片示例:

总结
所有页面都遵循 一个根布局,支持任意嵌套子布局 的规则,不同场景选择对应布局:
ColumnRowRelativeContainerStackFlex不同功能场景对应使用对应原生组件,开发效率更高:
Swiper | |
Video | |
Image | |
Text | |
TextInput | |
Button | |
Radio | |
Toggle |
这三个知识点是实现完整交互功能的核心,必须掌握:
@State状态管理:被@State修饰的变量是响应式变量,变量改变UI自动刷新,是「数据驱动视图」的核心基础AlertDialog.show()弹出系统原生弹窗,适合做操作结果提示、二次确认router.pushUrl()实现多页面跳转,还可以通过params传递参数,跳转前必须在main_pages.json注册所有页面这两个事件覆盖了绝大多数交互场景,语法固定非常好记:
onChange变化事件:输入框输入、开关状态变化时触发,用来把最新值同步给@State变量onClick点击事件:按钮、卡片等可点击元素触发,用来写点击后的业务逻辑(提交表单、跳转、弹窗等)