鸿蒙开发入门:Hello World

介绍

本节内容将帮助开发者学习如何构建一个全新的HarmonyOS应用,学习使用DevEco Studio创建新项目、使用预览器预览页面、了解基础组件如Image、Text等。

根据本教程【开发入门:Hello World】创建全新的项目。

根据教程中的提示使用01_Resources文件夹中的文件。

如果您想要自行探索,可以直接打开01_Complete文件夹中的项目并浏览代码。

项目文件下载

下载项目文件开始构建本项目,请根据以下步骤操作:

01_EnvironmentSetup.zip

创建一个新项目

使用DevEco Studio创建一个空项目,了解ArkUI模板代码和预览器的使用方法。

Step 1

搭建开发环境:

  1. 安装DevEco Studio,详情请参考下载安装软件
  2. 设置DevEco Studio开发环境,DevEco Studio开发环境需要依赖于网络环境,需要连接上网络才能确保工具的正常使用,详情请参考配置代理

Step 2

打开DevEco Studio,通过如下两种方式,打开工程创建向导界面:

如果当前未打开任何工程,可以在DevEco Studio的欢迎页,选择Create Project开始创建一个新工程。

如果已经打开了工程,可以在菜单栏选择File > New > Create Project来创建一个新工程。

Step 3

点击Create Project按钮后,跳转至Create Project页面,左侧可以选择创建应用或创建元服务。这里选择创建应用Application。选择Empty Ability模板,然后单击Next,进入配置界面。

Step 4

将Project name自定义为QuickStart。

检查Bundle name和Save location是否与命名一致,一般会根据Project name自行更新,也可以根据需要自行更改。

选择Compatible SDK为5.0.5(17),在编译构建时,DevEco Studio会根据指定的Compatible SDK版本进行编译打包。

开发者可以根据自己IDE版本选择高版本的Compatible SDK,本工程当前为5.0.5(17)。

DevEco Studio会默认勾选除‘Car’以外的全部Device type,保持该选项即可。

Step 5

单击Finish,工具会自动生成示例代码和相关资源。

等待工程创建完成,创建后界面如右图所示。

Step 6

在Project导航栏中选中 entry -> src -> main -> ets -> pages -> Index.ets,即可看到初始创建项目的模板代码。

 
  1. @Entry
  2. @Component
  3. struct Index {
  4. @State message: string = 'Hello World';
  5. build() {
  6. RelativeContainer() {
  7. Text(this.message)
  8. .id('HelloWorld')
  9. .fontSize($r('app.float.page_text_font_size'))
  10. .fontWeight(FontWeight.Bold)
  11. .alignRules({
  12. center: { anchor: '__container__', align: VerticalAlign.Center },
  13. middle: { anchor: '__container__', align: HorizontalAlign.Center }
  14. })
  15. .onClick(() => {
  16. this.message = 'Welcome';
  17. })
  18. }
  19. .height('100%')
  20. .width('100%')
  21. }
  22. }

Preview

其中,@Component装饰器装饰了struct关键字声明的数据结构Index。Index被@Component装饰后具备组件化的能力,通过实现build方法描述UI。

 
  1. @Entry
  2. @Component
  3. struct Index {
  4. @State message: string = 'Hello World';
  5. build() {
  6. RelativeContainer() {
  7. Text(this.message)
  8. .id('HelloWorld')
  9. .fontSize($r('app.float.page_text_font_size'))
  10. .fontWeight(FontWeight.Bold)
  11. .alignRules({
  12. center: { anchor: '__container__', align: VerticalAlign.Center },
  13. middle: { anchor: '__container__', align: HorizontalAlign.Center }
  14. })
  15. .onClick(() => {
  16. this.message = 'Welcome';
  17. })
  18. }
  19. .height('100%')
  20. .width('100%')
  21. }
  22. }

No Preview

@Entry装饰的@Component将作为UI页面的入口。在单个UI页面中,最多可以使用@Entry装饰一个自定义组件。

 
  1. @Entry
  2. @Component
  3. struct Index {
  4. @State message: string = 'Hello World';
  5. build() {
  6. RelativeContainer() {
  7. Text(this.message)
  8. .id('HelloWorld')
  9. .fontSize($r('app.float.page_text_font_size'))
  10. .fontWeight(FontWeight.Bold)
  11. .alignRules({
  12. center: { anchor: '__container__', align: VerticalAlign.Center },
  13. middle: { anchor: '__container__', align: HorizontalAlign.Center }
  14. })
  15. .onClick(() => {
  16. this.message = 'Welcome';
  17. })
  18. }
  19. .height('100%')
  20. .width('100%')
  21. }
  22. }

No Preview

界面由RelativeContainer相对布局容器作为根容器,RelativeContainer支持容器内部的子元素设置相对位置关系,适用于界面复杂场景的情况,对多个子组件进行对齐和排列。

 
  1. @Entry
  2. @Component
  3. struct Index {
  4. @State message: string = 'Hello World';
  5. build() {
  6. RelativeContainer() {
  7. Text(this.message)
  8. .id('HelloWorld')
  9. .fontSize($r('app.float.page_text_font_size'))
  10. .fontWeight(FontWeight.Bold)
  11. .alignRules({
  12. center: { anchor: '__container__', align: VerticalAlign.Center },
  13. middle: { anchor: '__container__', align: HorizontalAlign.Center }
  14. })
  15. .onClick(() => {
  16. this.message = 'Welcome';
  17. })
  18. }
  19. .height('100%')
  20. .width('100%')
  21. }
  22. }

No Preview

通过Text组件展示一段文本

 
  1. @Entry
  2. @Component
  3. struct Index {
  4. @State message: string = 'Hello World';
  5. build() {
  6. RelativeContainer() {
  7. Text(this.message)
  8. .id('HelloWorld')
  9. .fontSize($r('app.float.page_text_font_size'))
  10. .fontWeight(FontWeight.Bold)
  11. .alignRules({
  12. center: { anchor: '__container__', align: VerticalAlign.Center },
  13. middle: { anchor: '__container__', align: HorizontalAlign.Center }
  14. })
  15. .onClick(() => {
  16. this.message = 'Welcome';
  17. })
  18. }
  19. .height('100%')
  20. .width('100%')
  21. }
  22. }

No Preview

文本信息由@State装饰器装饰的状态变量message驱动。

 
  1. @Entry
  2. @Component
  3. struct Index {
  4. @State message: string = 'Hello World';
  5. build() {
  6. RelativeContainer() {
  7. Text(this.message)
  8. .id('HelloWorld')
  9. .fontSize($r('app.float.page_text_font_size'))
  10. .fontWeight(FontWeight.Bold)
  11. .alignRules({
  12. center: { anchor: '__container__', align: VerticalAlign.Center },
  13. middle: { anchor: '__container__', align: HorizontalAlign.Center }
  14. })
  15. .onClick(() => {
  16. this.message = 'Welcome';
  17. })
  18. }
  19. .height('100%')
  20. .width('100%')
  21. }
  22. }

No Preview

Text组件定义了组件标识id为HelloWorld,用于唯一指定组件。

 
  1. @Entry
  2. @Component
  3. struct Index {
  4. @State message: string = 'Hello World';
  5. build() {
  6. RelativeContainer() {
  7. Text(this.message)
  8. .id('HelloWorld')
  9. .fontSize($r('app.float.page_text_font_size'))
  10. .fontWeight(FontWeight.Bold)
  11. .alignRules({
  12. center: { anchor: '__container__', align: VerticalAlign.Center },
  13. middle: { anchor: '__container__', align: HorizontalAlign.Center }
  14. })
  15. .onClick(() => {
  16. this.message = 'Welcome';
  17. })
  18. }
  19. .height('100%')
  20. .width('100%')
  21. }
  22. }

No Preview

定义字体大小fontSize取值为$r('app.float.page_text_font_size')资源类型;定义文本的字体粗细fontWeight取值为Bold,即字体较粗。

 
  1. @Entry
  2. @Component
  3. struct Index {
  4. @State message: string = 'Hello World';
  5. build() {
  6. RelativeContainer() {
  7. Text(this.message)
  8. .id('HelloWorld')
  9. .fontSize($r('app.float.page_text_font_size'))
  10. .fontWeight(FontWeight.Bold)
  11. .alignRules({
  12. center: { anchor: '__container__', align: VerticalAlign.Center },
  13. middle: { anchor: '__container__', align: HorizontalAlign.Center }
  14. })
  15. .onClick(() => {
  16. this.message = 'Welcome';
  17. })
  18. }
  19. .height('100%')
  20. .width('100%')
  21. }
  22. }

No Preview

字体大小等数据的值一般存储在\entry\src\main esourcesase\element loat.json文件下,可以按照上文page_text_font_size的方式保存至float.json文件中,并通过$r('app.float.xxx')进行资源引用。

alignRules属性用于指定设置在相对容器中子组件的对齐规则,仅当父容器为RelativeContainer时生效,在这里定义Text组件横向居中和纵向居中。

 
  1. @Entry
  2. @Component
  3. struct Index {
  4. @State message: string = 'Hello World';
  5. build() {
  6. RelativeContainer() {
  7. Text(this.message)
  8. .id('HelloWorld')
  9. .fontSize($r('app.float.page_text_font_size'))
  10. .fontWeight(FontWeight.Bold)
  11. .alignRules({
  12. center: { anchor: '__container__', align: VerticalAlign.Center },
  13. middle: { anchor: '__container__', align: HorizontalAlign.Center }
  14. })
  15. .onClick(() => {
  16. this.message = 'Welcome';
  17. })
  18. }
  19. .height('100%')
  20. .width('100%')
  21. }
  22. }

No Preview

Step 7

开启右边栏的Previewer,预览器将工程中的@Entry作为实现入口,自动实现预览。

此处需要选中@Entry所在的文件,预览器才能顺利打开。

Step 8

修改APP的名称为“HMOS世界入门版”。修改entry/src/main/resources/base/element/string.json文件,将EntryAbility_label的value修改为“HMOS世界入门版”。

 
  1. {
  2. "string": [
  3. {
  4. "name": "module_desc",
  5. "value": "module description"
  6. },
  7. {
  8. "name": "EntryAbility_desc",
  9. "value": "description"
  10. },
  11. {
  12. "name": "EntryAbility_label",
  13. "value": "HMOS世界入门版"
  14. }
  15. ]
  16. }

Preview

Step 9

修改APP的图标。将01_Resources文件夹中的background.png和foreground.png图片进行复制粘贴到entry/src/main/resources/base/media文件夹中,将其中原本的background.png和foreground.png文件替换掉。

页面结构总览

创建好项目后,我们根据需要设计页面的结构进行分析,并确认页面的实现方式。

Step 1

抽象页面结构


我们想实现的页面效果如右图所示。

在右图中,我们将页面内的结构抽象三大部分。其中,第1部分为轮播图部分,第2部分为赋能套件部分,第3部分为入门教程部分。

轮播图部分:可自动播放、展示多张图片的组件,命名为Banner,每一个元素为BannerItem

赋能套件部分:横向可滑动的组件,命名为Enablement ,由多个EnablementItem组成。

入门教程部分:纵向可滑动的组件,命名为Tutorial ,由多个TutorialItem组成。

Step 2

选择布局实现页面

轮播图部分:Swiper组件提供滑动轮播显示的能力。

赋能套件部分:Grid组件为网格容器,由“行”和“列”分割的单元格所组成,其中容器内各条目对应一个GridItem组件。如果仅设置行、列数量与占比中的一个,网格单元将按照设置的方向排列,超出Grid显示区域后,Grid拥有可滚动能力。在这部分,可以设置单行显示,则赋能套件部分可以横向滑动。

入门教程部分:List容器可以轻松高效地显示结构化、可滚动的信息。当列表项达到一定数量,内容超过屏幕大小时,可以自动提供滚动功能。

接下来,我们将从最简单的步骤开始,一步步实现这个页面。

自定义文本视图

通过更改代码可以自定义视图,或者使用Inspector查询对应视图可更改的代码。 在设计布局时,DevEco Studio的Previewer工具可以实时提供反馈,以便观察代码如何转化为对应布局,反之,也可以根据布局效果调整代码。

Step 1

将原本Index文件中的内容并改为如右侧代码所示的内容。

更改 @State 装饰器装饰的状态变量message文字,可以驱动视图的更新。


将'Hello World'修改为'快速入门',这就是本应用程序中第一个页面的标题。可以看到,修改代码后,预览器会即时根据代码更新。

 
  1. @Entry
  2. @Component
  3. struct Index {
  4. @State message: string = '快速入门';
  5. build() {
  6. RelativeContainer() {
  7. Text(this.message)
  8. .id('HelloWorld')
  9. .fontSize(50)
  10. .fontWeight(FontWeight.Bold)
  11. .alignRules({
  12. center: { anchor: '__container__', align: VerticalAlign.Center },
  13. middle: { anchor: '__container__', align: HorizontalAlign.Center }
  14. })
  15. }
  16. .height('100%')
  17. .width('100%')
  18. }
  19. }

Preview

此处修改的是文本内容,需要手动保存(ctrl+s)后,预览器才会更新;如果修改的是相关属性,则不需要手动保存,预览器也会更新。

Step 2

如右图所示,点击Previewer工具栏的Inspector工具开启Inspector,可以观察到当前组件树,并与预览器交互。

点击组件树的部件,或者直接点击预览器视图中的元素,代码编辑器会自动跳转并框选至对应的代码块,同时显示相关信息。

Step 3

调整文本视图。


修改fontSize属性为24,fontWeight属性为700。可以看到随着代码的修改,预览器中的视图和代码编辑器的代码也会随之改变。

Step 4

如右图所示,观察可得,页面整体布局沿垂直方向布局。

将根容器从RelativeContainer更改为Column。


Column容器可以使组件内的元素沿垂直方向布局。删除Text组件的alignRules属性,这是由于alignRules属性在Column容器中不生效。删除Text组件的id属性,因为不需要识别该组件。

 
  1. @Entry
  2. @Component
  3. struct Index {
  4. @State message: string = '快速入门';
  5. build() {
  6. Column() {
  7. Text(this.message)
  8. .fontSize(24)
  9. .fontWeight(700)
  10. }
  11. .height('100%')
  12. .width('100%')
  13. .backgroundColor('#F1F3F5')
  14. }
  15. }

Preview

为整体组件添加背景色,取值为'#F1F3F5'。

 
  1. @Entry
  2. @Component
  3. struct Index {
  4. @State message: string = '快速入门';
  5. build() {
  6. Column() {
  7. Text(this.message)
  8. .fontSize(24)
  9. .fontWeight(700)
  10. }
  11. .height('100%')
  12. .width('100%')
  13. .backgroundColor('#F1F3F5')
  14. }
  15. }

Preview

Step 5

手动编辑代码,将'快速入门'置于屏幕左上角。


修改文本与屏幕左侧边距,首先将Text组件宽度设置为占满屏幕(100%),并设置文本对齐属性为Start,文本在Text组件内会向左对齐。

 
  1. @Entry
  2. @Component
  3. struct Index {
  4. @State message: string = '快速入门';
  5. build() {
  6. Column() {
  7. Text(this.message)
  8. .fontSize(24)
  9. .fontWeight(700)
  10. .width('100%')
  11. .textAlign(TextAlign.Start)
  12. }
  13. .height('100%')
  14. .width('100%')
  15. .backgroundColor('#F1F3F5')
  16. }
  17. }

Preview

设置文本左边距,padding属性可以设置内容器向内的边距,此处设置左边距(left)为16。

 
  1. @Entry
  2. @Component
  3. struct Index {
  4. @State message: string = '快速入门';
  5. build() {
  6. Column() {
  7. Text(this.message)
  8. .fontSize(24)
  9. .fontWeight(700)
  10. .width('100%')
  11. .textAlign(TextAlign.Start)
  12. .padding({ left: 16 })
  13. }
  14. .height('100%')
  15. .width('100%')
  16. .backgroundColor('#F1F3F5')
  17. }
  18. }

Preview

设置fontFamily字体属性为'HarmonyHeiTi-Bold',设置lineHeight行高属性为33。

 
  1. @Entry
  2. @Component
  3. struct Index {
  4. @State message: string = '快速入门';
  5. build() {
  6. Column() {
  7. Text(this.message)
  8. .fontSize(24)
  9. .fontWeight(700)
  10. .width('100%')
  11. .textAlign(TextAlign.Start)
  12. .padding({ left: 16 })
  13. .fontFamily('HarmonyHeiTi-Bold')
  14. .lineHeight(33)
  15. }
  16. .height('100%')
  17. .width('100%')
  18. .backgroundColor('#F1F3F5')
  19. }
  20. }

Preview

HarmonyHeiTi-Bold字体为较粗的鸿蒙黑体,已在DevEco Studio中内置,直接使用即可。

创建Image组件

在上一节中,我们创建了标题视图,接下来需要使用Image组件添加图片。Previewer可以直接预览@Entry装饰器装饰的整个页面,也可以预览由@Preview装饰器装饰的单独组件。 本节中将学习如何单独预览组件视图,并将视图组合进整个页面。

Step 1

在当前Index.ets文件内建立一个命名为Banner的空组件,并用@Preview装饰器装饰,以便单独预览组件。

 
  1. @Entry
  2. @Component
  3. struct Index {
  4. @State message: string = '快速入门';
  5. build() {
  6. Column() {
  7. Text(this.message)
  8. .fontSize(24)
  9. .fontWeight(700)
  10. .width('100%')
  11. .textAlign(TextAlign.Start)
  12. .padding({ left: 16 })
  13. .fontFamily('HarmonyHeiTi-Bold')
  14. .lineHeight(33)
  15. }
  16. .height('100%')
  17. .width('100%')
  18. .backgroundColor('#F1F3F5')
  19. }
  20. }
  21. @Preview
  22. @Component
  23. struct Banner {
  24. build() {
  25. }
  26. }

No Preview

Step 2

在Banner组件中添加图片。


首先,将01_Resources文件夹中的banner_pic1.png放置在entry -> src -> main -> resources -> base -> media路径下。

ArkUI提供了Image组件用于显示图片,此处使用$r('app.media. 文件名字')的方式将media文件夹下的图片读取到Image组件内。

设置图片的填充效果为Contain模式,即保持宽高比进行缩小或者放大,使得图片完全显示在显示边界内。

 
  1. @Entry
  2. @Component
  3. struct Index {
  4. @State message: string = '快速入门';
  5. build() {
  6. Column() {
  7. Text(this.message)
  8. .fontSize(24)
  9. .fontWeight(700)
  10. .width('100%')
  11. .textAlign(TextAlign.Start)
  12. .padding({ left: 16 })
  13. .fontFamily('HarmonyHeiTi-Bold')
  14. .lineHeight(33)
  15. }
  16. .height('100%')
  17. .width('100%')
  18. .backgroundColor('#F1F3F5')
  19. }
  20. }
  21. @Preview
  22. @Component
  23. struct Banner {
  24. build() {
  25. Image($r('app.media.banner_pic1'))
  26. .objectFit(ImageFit.Contain)
  27. }
  28. }

No Preview

Step 3

预览Banner组件。


将预览器调整至组件预览模式,可以单独观察到组件的视图预览。值得注意的是,此时的Inspector是不可用状态。

Step 4

组合标题和图片视图。


在@Entry装饰器装饰的Index组件中引入Banner组件,放在Text的下方,使用预览器预览完整视图。

 
  1. @Entry
  2. @Component
  3. struct Index {
  4. @State message: string = '快速入门';
  5. build() {
  6. Column() {
  7. Text(this.message)
  8. .fontSize(24)
  9. .fontWeight('700')
  10. .width('100%')
  11. .textAlign(TextAlign.Start)
  12. .padding({ left: 16 })
  13. .fontFamily('HarmonyHeiTi-Bold')
  14. .lineHeight(33)
  15. Banner()
  16. }
  17. .height('100%')
  18. .width('100%')
  19. .backgroundColor('#F1F3F5')
  20. }
  21. }
  22. @Preview
  23. @Component
  24. struct Banner {
  25. build() {
  26. Image($r('app.media.banner_pic1'))
  27. .objectFit(ImageFit.Contain)
  28. }
  29. }

Preview

Step 5

调整图片的属性以达到设计效果。


设置Image组件宽度为铺满整个屏幕

 
  1. @Preview
  2. @Component
  3. struct Banner {
  4. build() {
  5. Image($r('app.media.banner_pic1'))
  6. .objectFit(ImageFit.Contain)
  7. .width('100%')
  8. }
  9. }

Preview

设置图片与标题和边框的边距。

padding属性可以设置内容器向内的边距,此处设置左右边距(left、right)为16,上边距(top)为11。

 
  1. @Preview
  2. @Component
  3. struct Banner {
  4. build() {
  5. Image($r('app.media.banner_pic1'))
  6. .objectFit(ImageFit.Contain)
  7. .width('100%')
  8. .padding({ top: 11, left: 16, right: 16 })
  9. }
  10. }

Preview

设置图片四角的圆角值为16。

 
  1. @Preview
  2. @Component
  3. struct Banner {
  4. build() {
  5. Image($r('app.media.banner_pic1'))
  6. .objectFit(ImageFit.Contain)
  7. .width('100%')
  8. .padding({ top: 11, left: 16, right: 16 })
  9. .borderRadius(16)
  10. }
  11. }

Preview

至此,我们已经学会了如何自定义文本视图,以及使用Image组件加载资源文件展示图片。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

code_shenbing

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值