第一篇:
鸿蒙纪·系列教程#01 - 环境搭建与项目结构
《鸿蒙纪元》 是 张风捷特烈[1] 计划打造的一套 HarmonyOS 开发系列教程合集。致力于创作优质的鸿蒙原生学习资源,帮助开发者进入纯血鸿蒙的开发之中。本系列的所有代码将开源在 HarmonyUnit[2] 项目中:github: https://github.com/toly1994328/HarmonyUnit
gitee: https://gitee.com/toly1994328/HarmonyUnit
本文是《鸿蒙纪·梦始卷》 的第二章,上一篇介绍了环境搭建和初始项目,本篇将真正进入代码编写中,通过一个简单的计数器小功能,初步体验鸿蒙开发中的布局表现,以及交互行为:[3]. 简单了解组件的封装与拆分
HarmonyOS 应用开发使用的是 ArkUI 视图框架进行开发的,它也是一个 声名式 的 UI 框架。使用 TypeScript 的变种 ArkTs 语言进行开发。如果你有 Flutter 、 React 或 Compose 的开发经验,那么对 ArkUI 将驾轻就熟。计数器是我非常喜欢的一个小案例,点击按钮使界面上的数字增加。它虽然非常简单,但麻雀虽小五脏俱全。从中可以了解界面编程的基本布局特性,也可以了解事件的回调以及界面数据更新的方式:1. 列布局 Column 的背景和宽高
首先通过一个小案例看一下基本的布局特性,比如排列、背景色、边距、尺寸等。• ArkUI 中背景色是所有组件的通用属性,通过 backgroundColor 方法可以指定组件颜色。• Column 组件可以容纳多个组件,在自身区域内排布。@Component
struct Index {
build() {
Column() {
Text('计数器')
fontSize(28)
.fontWeight(FontWeight.Bold)
.backgroundColor('#440000ff')
}
.backgroundColor('#44ff0000')
}
}
上面代码中,让 Column 容纳一个 Text 文本,可以看出 Column 的区域尺寸默认是其容纳组件的尺寸:
• ArkUI 中的尺寸也是所有组件的通用属性,通过 width 和 height 设置。如下所示,将 Column 的 width 设置为 '100%',它将会横向铺满(红色示意)。并且其内容组件默认会 横向居中当把 Column 的 height 设置为 '100%' 时,可以看到红色区域会占满全屏,这也表示 Column 自身的区域尺寸。
2. 对齐方式与边距
Column 组件有控制内容组件对齐方式的属性,比如这里想让文字水平方向居左,可以设置 alignItems(HorizontalAlign.Start) 。Column 具体的布局特性,将在以后详细展开。现在想让文字离左边和上边有点边距,看上去不那么拥挤:
• ArkUI 中的边距也是所有组件的通用属性,通过 padding 和 margin 设置内边距和外边距。padding 表示内边距,内边距属于组件的区域尺寸,如下所示,Text 的区域被扩张:而外边距 margin 不会影响 Text 的实际区域尺寸,只是进行偏移:
如果去除 Text 颜色,两者在视觉表现上没有区别,但实际的布局效果是不同的。所以,在视图布局的学习过程中,设置背景色查看布局区域,可以很好地辅助理解布局特性。
3 计数器布局
Column 中可以容纳多个组件,如下所示,其中可以再放置一个粉色的 Column,此时高度 100% 会占据高度的剩余的部分。在粉色的 Column 中,放置两个文字组件,如下所示:
现在希望让两行文字在 竖直方向 居中显示,可以设置 Column 的 justifyContent 为 FlexAlign.Center 。此时去掉测试区域的颜色,就可以得到期望的计数器布局效果:
4.学习小技巧
到这里标记一个小的里程碑,下面是 Index.ets 的所有代码。可以通过 git 提交一下,大家可以通过每次的提交,记录当前的完整项目;同时,通过里程碑,也可以回顾自己开发过程的点滴成长。我也会在每个小里程碑放上一个提交记录,大家可以直接访问链接查看代码: 计数器-布局-v1[3]@Entry
@Component
struct Index {
@State message: string = '鸿蒙纪元';
build() {
Column() {
Text('计数器')
.fontSize(28)
.fontWeight(FontWeight.Bold)
.margin({ top: 20, left: 20 })
Column() {
Text('下面是你点击按钮的次数:')
.fontSize(18)
Text('0')
.fontSize(36)
.fontColor('#2e3032')
.margin({ top: 10 })
}
.width('100%')
.height('100%')
.justifyContent(FlexAlign.Center)
}
.alignItems(HorizontalAlign.Start)
.width('100%')
.height('100%')
}
}
由于布局组件的属性和方法比较多,大家在学习过程中可以有意的记录一下遇到的知识点,有利于梳理、积累、沉淀:
这一小节我们将实现如下的布局界面,并实现按钮点击时增加计数器的数值:1. 按钮和图标的展示
通过 Button 可以展示按钮,type 设置为 ButtonType.Circle 以圆形展示;stateEffect 为 true 时,点击可以有颜色加深的反馈效果。
图标通过 SymbolGlyph 组件展示,可以加载系统内置的图标资源。所以得资源可以在官方的 harmonyos-symbol[4] 中查看。使用 fontSize 设置大小、fontColor 设置颜色、fontWeight 设置字重。Button({ type: ButtonType.Circle, stateEffect: true }) {
SymbolGlyph($r('sys.symbol.plus'))
.fontSize(24)
.fontColor([Color.White])
.fontWeight(FontWeight.Bold)
}.width(56).height(56)
2. Stack 层叠布局
层叠布局可以让对个组件自下而上层层排列,通过 alignContent 可以设置子组件的对齐方式,比如这里设置为右下方 BottomEnd,按钮也就对齐到右下。可以通过对按钮设置外边距空出右侧和下方的间隔,从而完成想要的布局效果:3. 简单的状态变化
我们称界面上随交互变化的数据为 可变状态量,比如当前需求下,可变状态量是呈现的数值,会随着按钮点击交互而增加。组件内部可以通过 @State 声明可变状态量,即如下的 counter 变量。按钮可以通过 onClick 设置点击的回调事件监听,只需要触发 counter 增加,界面上的数值就会自动更新渲染:struct Index {
@State counter: number = 0;
Button(//略同...
.onClick(()=>this.counter++ )
这里按钮触发的逻辑只有一行,这样写起来比较简单。如果是比较复杂的逻辑,建议提取一个函数(方法) 进行处理,更利于分离视图构建逻辑和行为数据逻辑 的代码,比如提取 increment 方法处理数据增加的业务逻辑; 按钮点击时触发 this.increment 即可。这样如果行为需求有什么变更,直接在 increment 方法中处理即可,方便定位代码和拓展功能:increment(): void {
this.counter++;
}
Button(//略同...
.onClick(()=>this.increment() )
大家可以继续梳理一下已经遇到的知识点,计数器的基本功能完成了,可以再提交一个小里程碑 计数器-v2-基本功能[5]
目前项目中,所有的代码都放在一块,点击这里查看 Index.ets[6]。嵌套结构看起来可读性很差。随着后面功能需求的增加,代码量会激增。学会合理地拆分组件,进行独立维护,是个很好的习惯。比如头部标题栏是一个相对独立的区域,以后可能有被修改 和复用的可能,就可以将它视为一个组件来单独维护。使用 @Component 声明一个组件,在其中的 build 方法中处理构建逻辑:1. 拆分 AppBar
应用的头部栏可以被其他界面复用,也会遇到修改的需求。适合拆分出来单独处理,比如下面使用 @Component 声明一个 AppBar 组件,构造是可以传入 title 字符串指定展示的标题文字。这里通过 Row 组件可以让若干个子组件横向排列,通过 justifyContent(FlexAlign.Center) 可以让子组件居中对其:@Component
struct AppBar {
private title: string = '';
build() {
Row() {
Text(this.title)
.fontSize(20).fontWeight(FontWeight.Bold)
.fontColor($r('sys.color.white'))
}
.backgroundColor('#317bd4')
.width('100%')
.height(56)
.padding({ left: 20, right: 20 })
.justifyContent(FlexAlign.Center)
}
}
如果其他界面中也需要构建类似的头部栏,每次都写一遍的话很不优雅。布局结构是类似的,无非是一些配置属性的差异,可以通过构造传参来指定数据。如下所示,AppToolBar 可以通过 title 指定文字标题:如果你有其他的自定义属性,可以自行添加,比如背景色、高度等。对于组件构建来说,设置插槽可以增加布局的灵活性。比如 AppBar 的首尾部分,使用者想要自己传入组件,来满足更多样化的使用场景:
那左侧的 leading 来说,通过 @BuilderParam 声明是组件构建者参数;通过 leadingBuilder 设置默认的构建器。构建器需要通过 @Builder 注解标识:@Component
struct AppBar {
private title: string = '';
@Builder
leadingBuilder() {}
@Builder
tailingBuilder() {}
@BuilderParam leading: () => void = this.leadingBuilder;
@BuilderParam tailing: () => void = this.tailingBuilder;
build() {
Row() {
this.leading()
Text(this.title)
.fontSize(20).fontWeight(FontWeight.Bold)
.fontColor($r('sys.color.white'))
this.tailing()
}
.backgroundColor('#317bd4')
.width('100%')
.height(56)
.padding({ left: 20, right: 20 })
.justifyContent(FlexAlign.SpaceBetween)
}
}
这样在 AppBar 构造时,可以通过 leading 参数,让外界构建具体内容,插入到 AppBar 结构的内部。通过这种方式,我们就可以封装一些通用的结构,便于复用:到此,我们遇到的几个注解也可以整理一些,进入知识树中。知识树在一开始并不需要尽善尽美,它是你点滴的积累。可以在后续不断随着知识累计,调节各个枝点。这里再提交一个小里程碑 计数器-v3-组件简单封装[7]
到这里,我们就已经完成了一个简单的计数器功能,并简单地认识鸿蒙开发中界面的布局已经组件封装。下一章我们将继续完善当前的计数器,了解沉浸标题栏、资源文件的使用、国际化的处理、布局调试工具的使用,敬请期待 ~
引用链接
[1] 张风捷特烈:
https://juejin.cn/user/149189281194766
[2] HarmonyUnit:
[3] 计数器-布局-v1:
https://github.com/toly1994328/HarmonyUnit/tree/8c15c41e5577312c33440e5fdbbcceda173b80e5
[4] harmonyos-symbol:
https://developer.huawei.com/consumer/cn/design/harmonyos-symbol
[5] 计数器-v2-基本功能:
https://github.com/toly1994328/HarmonyUnit/tree/994916b2e1866bb1898dfb9fe348b231261c8767
[6] 点击这里查看 Index.ets:
https://github.com/toly1994328/HarmonyUnit/blob/994916b2e1866bb1898dfb9fe348b231261c8767/entry/src/main/ets/pages/Index.ets
[7] 计数器-v3-组件简单封装:
https://github.com/toly1994328/HarmonyUnit/tree/994916b2e1866bb1898dfb9fe348b231261c8767
[8] 张风捷特烈:
https://juejin.cn/user/149189281194766
[9] 张风捷特烈:
https://space.bilibili.com/390457600
最后推荐一下我做的网站,玩Android: wanandroid.com ,包含详尽的知识体系、好用的工具,还有本公众号文章合集,欢迎体验和收藏!
推荐阅读:
扫一扫 关注我的公众号
如果你想要跟大家分享你的文章,欢迎投稿~
┏(^0^)┛明天见!