harmonyOS基础- 快速弄懂HarmonyOS ArkTs基础组件、布局容器(前端视角篇)
大家好!我是黑臂麒麟,一位6年的前端;
if you're change the world, you're workingon important things. you're excited to get up in the norning.
一、常用基础组件
1.基础组件
简单列举常用的及含义,掌握了以下按钮可以解决日常简单场景需求。其他在使用时查询ArkTS的API文档即可。
| 组件 | 含义 |
|---|---|
| Text() | 显示一段文本的组件。 |
| Image() | 图片组件,支持本地图片和网络图片的渲染展示 |
| TextInput() | 单行文本输入框组件。 |
| Button() | 按钮 |
| Blank | 空白填充组件,在容器主轴方向上,空白填充组件具有自动填充容器空余部分的能力。仅当父组件为Row/Column时生效。 |
| LoadingProgress | 显示加载进展 |
| ... |
2.文本样式
ArkTS的样式以驼峰命名方式,这里以Text组件为例:
| 名称 | 参数类型 | 描述 |
|---|---|---|
| fontColor | ResourceColor | 设置文本颜色 |
| fontSize | Length or Resource | 设置文本颜色 |
| fontStyle | FontStyle | 设置文本的字体样式。默认值:FontStyle.Normal。 |
| fontWeight | numbe or FontWeight or string | 设置文本的字体粗细,number类型取值[100, 900],取值间隔为100,默认为400,取值越大,字体越粗。string类型仅支持number类型取值的字符串形式,例如“400”,以及“bold”、“bolder”、“lighter”、“regular”、“medium”,分别对应FontWeight中相应的枚举值。默认值:FontWeight.Normal。 |
下面代码是两个Text组件,分别是默认样式和设置了文本样式的对比。
@Entry
@Component
struct Index {
@State message: string = 'Hello World';
@State myText: string = 'World';
build() {
Row() {
Column(){
Text('ArkTs')
Text('ArkTs')
.fontColor(Color.Blue)
.fontSize(40)
.fontWeight(FontWeight.Bold)
.fontFamily('Arial')
}
}
.justifyContent(FlexAlign.Center)
.backgroundColor(0xF1F3F5)
.width('100%')
.height('100%')
}
}

以上ArkTs代码的样式使用驼峰格式;其他组件的样式也是一样。使用时查阅具体用法。
3.Image
这里着重说一下Image的图片地址的引入方式,方式如下:
Image(src: string|PixelMap|Resource)
(1).使用string数据加载网络图片
Image(‘https://www.example.com/xxx.png’)
这里要注意Image在使用网络图片的时候,需要要在module.json5文件中声明网络访问权限
// module.json5
{
"module": {
"requestPermissions": [
"name": "ohos.permisssion.INTERNET"
]
}
}
(2).使用PixelMap数据加载图片
Image(pixelMapObject)
(3)使用Resource数据加载图片
Image($r('app.media.logo'))
上面的Resource是一种资源引入类型。会在下面详细描述。
4.使用资源引用类型
Resource是资源引用类型,用于设置组件属性的值。ArkTs文档推荐优先使用Resource类型,将资源文件(字符串、图片、音频等)统一存放于resources目录下,便于开发者统一维护。同事系统可以根据当前配置加载合适资源,例如,开发者根据屏幕尺寸呈现不同的布局效果,或根据语言提供不同的字符串。
已上面Text组件代码为例:
Text('ArkTs')
.fontColor(Color.Blue)
.fontSize(40)
.fontWeight(FontWeight.Bold)
.fontFamily('Arial')
(1).对元素内文本字符串的管理;
可以将这些编码写到entry/src/main/resources下的资源文件中。

在string.json中定义Button显示的文本

就个人而言,不太喜欢这种方式相对于前端喜欢而言。
在float.json中定义Text的字体样式。

在color.json中定义Text的字体颜色。

然后再Text组件通过$r('app.type.name)的形式引用应用资源。app带表应用内resources目录中定义的资源;type代表资源类型(或资源的存放位置),可以取“color”,“float”、“string”、“plural”、“media”; 以上几种是固定的,不支持自定义命名文件引用。name代表资源命名,由开发者定义资源时确定的。
Text($r('app.string.Index_Text'))
.fontColor($r('app.color.Text_color'))
.fontSize($r('app.float.Text_fontSize'))
.fontWeight(FontWeight.Bold)
.fontFamily($r('app.float.Text_fontFamily'))
以上是简单的描述Resource引用方式,后面回单独出一期深入研究的Resource引入文章。
二、布局组件
前端常用布局方式header、side、main、footer等标签,还有布局样式flex、grid等,在ArkTs常用布局组件有一下几种:
| 组件 | 描述 |
|---|---|
| Column | 垂直方向布局的容器 |
| Row | 水平方向布局的容器 |
| List | 列表容器 |
| Grid | 网格容器 |
| Tabs | 页签容器 |
| Swiper | 滑块视图容器 |
| Scroll | 可滑动的容器 |
这里说一下List,Grid,Tabs,Column、Row使用方法,Swiper、Scroll布局组件相对简单详见Api文档。有点类似小程序的类似组件。
1. Column&Row
布局容器概念
线性布局容器表示垂直方向或者水平方向排列子组件的容器,ArkTs提供了Column和Row容器来实现线性布局。
主轴和交叉轴概念
在布局容器中,默认存在两根轴,分别是主轴和交叉轴,这两个轴始终是相互垂直的。不同的容器中主轴的方向不一样的。
- 主轴:在Column容器中的子组件是按照
从上到下的垂直方向布局,其主轴的方向是垂直方向;在Row容器中的组件时按照从左到右的水平方向布局的,其主轴的方向时水平方向。
下图时Column&Row容器交叉轴

属性
Column&Row容器的两个属性justifyContent和alignItems,类似CSS的flex或Grid的justify-content和align-item。这样容易让我们前端快速理解。
这里注意一下它们的属性值都要首字母大写。
| 属性名称 | 描述 |
|---|---|
| justifyContent | 设置子组件在主轴方向上的对齐格式 |
| alignItems | 设置子组件在交叉轴方向上的对齐格式 |
主轴方向的对其(justifyContent)
子组件在主轴方向上的使用jusifyContent属性来设置,其参数类型时FlexAlign。它有一下几种类型:
| 属性值 | 描述 |
|---|---|
| Start | 主轴方向首端对齐,第一个元素与行首对齐,同时后续的元素与前一个对齐 |
| Center | 主轴方向中心对齐,第一个元素与行首的距离以及最后一个元素与行尾距离相同 |
| End | 主轴方向尾部对齐,最后一个元素与行尾对齐,其他元素与后一个对齐 |
| SpaceBetween | 主轴方向均匀分配弹性元素,相邻元素之间距离相同。 第一个元素与行首对齐,最后一个元素与行尾对齐 |
| SpaceAround | 轴方向均匀分配弹性元素,相邻元素之间距离相同。 第一个元素到行首的距离和最后一个元素到行尾的距离是相邻元素之间距离的一半 |
| SpaceEvenly | 主轴方向等间距布局,无论是相邻元素还是边界元素到容器的间距都一样 |
Start

Center

End

SpaceBetween

SpaceAround

SpaceEvenly

交叉中方向对齐(alignItems)
Column容器的主轴时垂直方向,交叉轴是水平方向,其参数类型为HorizontalAlign(水平对齐),HorizontalAlign定义了一下几个类型;
| 属性值 | 描述 |
|---|---|
| Start | 水平方向上按照起始端对齐 |
| Center | 水平方向上居中对齐 |
| End | 水平方向上按照末端对齐 |
start

Centent

End

Row容器的主轴是水平方向,交叉轴是垂直方向,其参数类型为VerticalAlign(垂直对其),VerticalAlign定义了一下几种类型:
|属性值|描述|
|--|--|
|Top|垂直方向上居顶部对齐|
|Center|竖直方向上居中对齐|
|Bottom|竖直方向上居底部对齐|Top

Center

Bottom

接口介绍
Column&Row都课接收一个参数space,表示子组件在主轴上的间距;
@Entry
@Component
struct Index {
@State TextArr: Array<string> = ["Image", "Text", "TextInput", "Button"]
build() {
Column({space: 30}) { // 这里设置子元素主轴上的间距
ForEach(this.TextArr, (item: string)=> { // 利用ForEach渲染我们的字符串数组
Row(){
Text(item)
}
.width('80%')
.height('100vp')
.backgroundColor('#99b2df')
.border({
width: 5,
color: '#8aa7da',
style: BorderStyle.Solid
})
.justifyContent(FlexAlign.Center)
})
}
.justifyContent(FlexAlign.Start)
.backgroundColor('#bdd7ee')
.width('100%')
.height('100%')
}
}
渲染出来的效果:

3. List使用
简介
使用频率很高的组件,需要配合ListItem子组件一起使用,列表每项对应一个ListItem组件

使用ForEach渲染
渲染多时,可以使用ForEach来循环渲染我们的列表项;
@Entry
@Component
struct Index {
private arr: number[] = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
build() {
Column({space: 30}) {
List({space: 10}) {
ForEach(this.arr, (item: number)=> {
ListItem(){
Text(`${item}`)
.width('100%')
.height(100)
.fontSize(20)
.fontColor(Color.White)
.textAlign(TextAlign.Center)
.backgroundColor(0x007DFF)
}
}, item => item)
}
}
.padding(12)
.height('100%')
.backgroundColor(0xF1F3F5)
}
}

设置分割线
这里如有需求可以给list组件可以使用divider属性给ListItem设置分割线。有四个参数:
- strokeWidth: 分割线宽度
- color: 分割线颜色
- startMargin: 分割线距离列表起始端的距离
- endMargin: 分割线距离列表结束端的距离
List({space: 50}) {
ForEach(this.arr, (item: number)=> {
ListItem(){
Text(`${item}`)
}
}, item => item)
}
.divider({
strokeWidth: 5,
color: '#d8d8d8',
startMargin: 20,
endMargin: 20,
})

列表滚动事件监听
List滚动监听事件和前端监听Scroll监听时间方法很像:
onScroll: 滑动触发,返回scrollOffset为滑动偏移量,scrollState为当前滑动状态。onScrollIndex: 滑动时触发,分别返回滑动起始索引值与滑动结束索引值。onReachStart: 列表到达起始位置时触发。onReachEnd:列表到底末尾位置触发。onScrollStrop: 列表滑动结束时触发。

利用这些时间监听,并可以在log面板中打印出我们想要的滑动数据;
设置List排列方向
List组件排列可以垂直方向和水平方向排列,默认是垂直方向排列。如果想设置List为水平方向,可以使用listDiretion属性为Axis.Horizontal即可。
4. Grid
简介
如果前端学过css的grid布局模式,那大家一定不会对Grid组件布局陌生,接下来学习如何使用Grid网格布局组件。
使用
Grid组件是由“行”和“列”分割的单元格组成。Grid一般和GridItem一起使用。
@Entry
@Component
struct GridPage {
private arr: string[] = new Array(9).fill('').map((_, index) => `item ${index + 1}`)
build() {
Column() {
Grid() {
ForEach(this.arr, (item: string) => {
GridItem(){
Text(item)
.fontSize(16)
.fontColor(Color.White)
.backgroundColor(0x007DFF)
.width('100%')
.height('100%')
.textAlign(TextAlign.Center)
}
}, (item: string) => item)
}
.columnsTemplate('1fr 1fr 1fr')
.rowsTemplate('1fr 1fr 1fr')
.columnsGap(10)
.rowsGap(10)
.height(300)
}
.width('100%')
.padding(12)
.backgroundColor(0xF1F3F5)
}
}

这里我们同样跟List一样使用ForEach遍历出的数组,可以看到我们设置columnsTemplate属性垂直方向配置3等分个1fr,同样纵向rowsTemplate也是3等分的1fr,1fr代表所占Grid等分个数。columnGap和rowGap分别设置垂直和纵向元素之间的间距。这里分别设置了 10vp。
5. Tabs
概述
Tabs是我们常用的做视图切换的常用布局组件。如“底部页签”,“顶部标签”,平板的“侧边页签”等。
使用
Tabs组件仅含子组件TabContent,每一个页签对应内容视图即TabContent组件。
结合之前我们写的List和Grid的组件,我们编写一个简单的Tabs布局
import Home from '../view/Home';
import GridPage from '../view/GridPage'
@Entry
@Component
struct Index {
private controller: TabsController = new TabsController();
build() {
Column() {
Tabs() {
TabContent() {
Home()
}
.tabBar('List')
TabContent() {
GridPage()
}
.tabBar('Grid')
}
.barWidth('100%') // 设置TabBar宽度
.barHeight('60') // 设置TabBar高度
.width('100%')
.height('100%')
.backgroundColor(0xF5F5F5)
}
.width('100%')
.height('100%')
}
}
展示后的效果


上面代码,通过属性width和height设置了Tabs组件的宽高,使用TabWidth和BarHeight设置了TabBar的宽度和高度。

设置TabBar布局属性
Tabs布局模式默认Fixed的,不支持滑动。如果页签过多会可能导致显示不全,讲布局模式设置为Scrollable的话,可以实现页签的滚动。
| 布局属性 | 描述 | 属性值 |
|---|---|---|
| barMode | Tabs的布局模式 | BarMode.Fixed (默认):所有TabBar平均分配barWidth宽度。 BarMode.Scrollable: 每个TabBar使用实际宽度,超过总长度后可滑动。 |
| barPosition | 设置TabBar位置和排列方向 | BarPosition.Start,vertical属性为false(默认值)时,页签在顶部.vertical属性为true时,位于容器左侧。 BarPosition.End, vertical属性为false时,位于容器底部。vertical属性为true时,位于容器右侧。 |
自定义TabBar样式
如果需要自定义TabBar, 需要通过@Builder装饰器的函数。构造一个生成自定义TabBar样式的函数,我们来实现上面底部页签效果:
import Home from '../view/Home';
import GridPage from '../view/GridPage'
@Entry
@Component
struct Index {
private tabsController: TabsController = new TabsController();
@State currentIndex: number = 0;
@Builder TabBuilder(title: string, targetIndex: number, selectedImg: Resource, normalImg: Resource) {
Column() {
Image(this.currentIndex === targetIndex ? selectedImg : normalImg)
.size({width: 25, height: 25})
Text(title)
.fontColor(this.currentIndex === targetIndex ? '#1698CE' : '#6B6B6B')
}
.width('100%')
.height(50)
.justifyContent(FlexAlign.Center)
.onClick(() => {
this.currentIndex = targetIndex;
this.tabsController.changeIndex(this.currentIndex);
})
}
build() {
Column() {
Tabs({barPosition: BarPosition.End, controller: this.tabsController}) {
TabContent() {
Home()
}
.tabBar(this.TabBuilder('List', 0, $r('app.media.home_selected'), $r('app.media.home_normal')))
TabContent() {
GridPage()
}
.tabBar(this.TabBuilder('List', 1, $r('app.media.mine_selected'), $r('app.media.mine_normal')))
}
.vertical(false)
.barWidth("100%") // 设置TabBar宽度
.barHeight(60) // 设置TabBar高度
.width('100%')
.height('100%')
.backgroundColor(0xF5F5F5)
.onChange((index: number) => {
this.currentIndex = index;
})
}
.width('100%')
.height('100%')
}
}
渲染后效果:

将barPosition的值设置为BarPosition.End,使页签显示在底部。使用@Builder自定义TabBuilder函数,生成由Image和Text组成的页签。同时也给Tabs组件设置了TabsController控制器,当点击某个页签时,调用changeIndex方法进行页签内容切换。
最后在Tabs添加onChange事件。切换时,把当前最近Index赋给currentIndex保存起来。
参考
华为开发者联盟官网开发者基础课程
harmonyOS基础- 快速弄懂HarmonyOS ArkTs基础组件、布局容器(前端视角篇)的更多相关文章
- 如何快速弄懂Java线程池
Java线程池是一种高效的多线程编程技术,它可以帮助程序员有效地控制多线程的并发执行.它可以提高应用程序的性能.降低内存消耗和减少延迟. 线程池的原理是,程序员可以将每个任务放入线程池中,然后由线程池 ...
- Python 零基础 快速入门 趣味教程 (咪博士 海龟绘图 turtle) 3. 循环
在前面的教程中,咪博士留了一道练习题给大家—-画正方形,相信聪明的你应该已经画出来了. 下面是咪博士实现的代码. 是不是跟你的代码很像呢? import turtle turtle.forward(2 ...
- vue 快速入门 系列 —— vue 的基础应用(上)
其他章节请看: vue 快速入门 系列 vue 的基础应用(上) Tip: vue 的基础应用分上下两篇,上篇是基础,下篇是应用. 在初步认识 vue一文中,我们已经写了一个 vue 的 hello- ...
- [web建站] 优课急送《零基础快速学习建站》视频+课件【价值399元】
[课程介绍]你想快速建一个网站出来吗?你想从什么都不懂到一两天出一个漂漂亮亮的站吗?你想完成领导交给你的任务找人建站吗?你想自己建站来创业吗?你想学会建站之后,利用给别人建站来赚钱吗?你想建一个跟某个 ...
- php随笔3-thinkphp 学习-ThinkPHP3.1快速入门(1)基础
ThinkPHP3.1快速入门(1)基础 简介 ThinkPHP是一个快速.简单的基于MVC和面向对象的轻量级PHP开发 框架,遵循Apache2开源协议发布,从诞生以来一直秉承简洁实用的设计原则,在 ...
- 序言 - PHP零基础快速入门
我为什么要写<PHP零基础快速入门>? 原因: PHP 真心简单,适合零基础的人快速入门掌握,身边的人学习一两周上手开发的比比皆是: 市面上的文章或书籍对初学者并不友好,多半枯燥乏味,我相 ...
- 零基础快速入门web学习路线(含视频教程)
下面小编专门为广大web学习爱好者汇总了一条完整的自学线路:零基础快速入门web学习路线(含视频教程)(绝对纯干货)适合初学者的最新WEB前端学习路线汇总! 在当下来说web前端开发工程师可谓是高福利 ...
- Python 零基础 快速入门 趣味教程 (咪博士 海龟绘图 turtle) 7. 条件循环
条件循环能够让程序在条件成立时(即为真时)重复执行循环体中的语句.如果条件一直成立(即永远不会为假),则循环会一直进行下去,不会停止.如果初始时,条件不成立,则循环 1 次也不会执行.Python 中 ...
- Python 零基础 快速入门 趣味教程 (咪博士 海龟绘图 turtle) 6. 条件
前面的教程中,我们已经可以让小海龟绘制出各种图形了.但是,所有绘图的代码都是预先编好的,程序一旦运行起来,运行结果(绘制的图形)就是固定不变的.这一节中,咪博士将教大家如何让海龟响应用户的输入. im ...
- Python 零基础 快速入门 趣味教程 (咪博士 海龟绘图 turtle) 5. 参数
上一个教程中,咪博士带大家学习了函数的使用.例如,line_without_moving 函数,可以让海龟先画出一条线段,然后再回来起点. def line_without_moving(): tur ...
随机推荐
- ORACLE事物隔离级别和脏读、幻读、不可重复读区别
一.事务和隔离级别 事务的概念:事务是把对数据库的一系列操作都看做一个整体,要么全部成功,要么全部失败,利用事务我们可以保证数据库的完整性,事务具有原子性. 隔离级别:隔离级别定义了事务与事务之间的隔 ...
- oracle19.3打补丁
补丁 36582781 - 数据库发布更新 19.24.0.0.240716 本文档在发布时准确无误.有关数据库版本更新 19.24.0.0.240716 的任何更改和其他信息,请参阅 My Orac ...
- 从拼积木到最长连续序列:一道别出心裁的数组题目|LeetCode 128 最长连续序列
LeetCode 128 最长连续序列 点此看全部题解 LeetCode必刷100题:一份来自面试官的算法地图(题解持续更新中) 生活中的算法 你小时候一定玩过数字积木吧?一堆写着不同数字的积木块散落 ...
- Spring Boot项目设置跨域
一.跨域设置 新建一个配置类 import java.io.IOException; import javax.servlet.Filter; import javax.servlet.FilterC ...
- Codeforces 1110D Jongmah 题解 [ 蓝 ] [ 线性 dp ] [ 观察 ]
Jongmah:小清新麻将 dp 题. 观察 首先观察这两个操作的性质,不难发现我们出掉的所有的顺子只要累计出了三次,这三次顺子就一定可以化作出三次相同的单牌. 而我们只需要最大化操作次数,显然这三次 ...
- Luogu P7250 BalticOI 山峰 题解 [ 蓝 ] [ 模拟 ] [ 并查集 ] [ BFS ]
Luogu P7250 BalticOI 山峰. 一道大模拟,很暴力,也很难写.建议紫或蓝,标签为模拟.广度优先搜索.并查集. 思路 首先观察到答案取决于路线上的最低点,所以我们可以把所有点的高度丢进 ...
- flutter-超出部分隐藏
第一种写法 1 ConstrainedBox( 2 constraints: BoxConstraints( 3 maxHeight: 100 4 ), 5 child: Stack( 6 overf ...
- vivo HTTPDNS 端到端体验优化实践
作者:来自 vivo 互联网运维团队- Zhang Qianqian 在信息时代,用户的手机应用访问量日益增多,DNS 解析作为连接互联网的关键环节,也被提出了更高要求.这一背景下,HTTPDNS 域 ...
- CF895C Square Subsets 题解
看到 \(a_i\le 70\) 后,发现 \(n\) 啥用没有,因为只需要枚举 \(1-70\) 选几个即可. 看到求完全平方数后,想到分解质因数,由于 \(a_i\le 70\),所以只有 \(1 ...
- 远程debug
1. 在idea中添加远程服务器信息 打开应用配置 填写配置 1. 在 + 选择 Remote JVM Debug 2. 在 2 处填写名称,任意 3. 在 3 填写服务器ip 4. 在 4 填写de ...