【鸿蒙】HarmonyOS NEXT应用开辟快速入门教程之结构篇(下)

[复制链接]
发表于 2025-12-30 00:38:28 | 显示全部楼层 |阅读模式
系列文章目次

【鸿蒙】HarmonyOS NEXT开辟快速入门教程之ArkTS语法装饰器(上)
【鸿蒙】HarmonyOS NEXT开辟快速入门教程之ArkTS语法装饰器(下)
【鸿蒙】HarmonyOS NEXT应用开辟快速入门教程之结构篇(上)
【鸿蒙】HarmonyOS NEXT应用开辟快速入门教程之结构篇(下)
【鸿蒙】HarmonyOS Next 组件或页面之间的全部通讯(传参)方法总结

系列文章目次2

HarmonyOS Next 系列之省市区弹窗选择器实现(一)
HarmonyOS Next 系列之验证码输入组件实现(二)
HarmonyOS Next 系列之底部标签栏TabBar实现(三)
HarmonyOS Next 系列之HTTP哀求封装和Token恒久化存储(四)
HarmonyOS Next 系列之从手机选择图片或照相上传功能实现(五)
HarmonyOS Next 系列之可移动悬浮按钮实现(六)
HarmonyOS Next 系列之沉醉式状态实现的多种方式(七)
HarmonyOS Next系列之Echarts图表组件(折线图、柱状图、饼图等)实现(八)
HarmonyOS Next系列之舆图组件(Map Kit)利用(九)
HarmonyOS Next系列之半圆环进度条实现(十)
HarmonyOS Next 系列之列表下拉革新和触底加载更多数据实现(十一)
HarmonyOS Next系列之实现一个左右袒露中央大双方小带缩放动画的轮播图(十二)
HarmonyOS Next系列之水波纹动画殊效实现(十三)




媒介

HarmonyOS NEXT(鸿蒙应用)开辟快速入门教程之结构篇(下),基于HarmonyOS NEXT Beta1版本(api 12)讲授。
   本文将从前端开辟者角度来学习鸿蒙的结构语法,通过类比鸿蒙结构和web css结构相似之处,资助各人快速把握鸿蒙结构开辟。
  
一、常见结构详细利用

(4)相对结构(RelativeContainer)

   此相对结构非css内里的相对结构而是安卓内里的相对结构,对于web开辟职员来说比力新的一种结构方式,而对于安卓开辟来说就非常认识,css相对结构在鸿蒙内里也有类似用法后续会讲到。
  RelativeContainer为采取相对结构的容器,支持容器内部的子元素设置相对位置关系,实用于界面复杂场景的环境,对多个子组件举行对齐和分列。子元素支持指定兄弟元素作为锚点,也支持指定父容器作为锚点,基于锚点做相对位置结构。
普通先容说就是子元素放置位置既可以设置相对父容器,也可以设置相对兄弟组件,相对父元素就可以看做在一个密闭长方形空间你想把东西放置它的上下左右某个对齐方向上,相对兄弟组件可以当作两个盒子,让盒子上面对齐分列大概盒子上和另一个盒子下对齐,左对齐大概左与右对齐确定子元素位置。以是这边相对的是其他组件而css的相对的是自己,因此必须设置相对的元素,这个元素称为锚点。
1、根本概念:

锚点:通过锚点设置当前元素基于哪个元素确定位置。
对齐方式:通过对齐方式,设置当前元素是基于锚点的上中下对齐,照旧基于锚点的左中右对齐。
2、语法提炼:

  1. RelativeContainer() {
  2.   子组件().alignRules({
  3.      方向(left或right或top或bottom):{anchor:锚点ID,align:对齐枚举值},
  4.      方向(left或right或top或bottom):{anchor:锚点ID,align:对齐枚举值},
  5.      ....
  6.      
  7.   })
  8. }
复制代码
一样平常设置2个方向就能确定位置了,好比left+top,如果子组件未设置高度或宽度的,也可以通过设置3个以上方向让子组件拉伸填满父组件宽度或高度。
   为了明确界说锚点,必须为RelativeContainer及其子元素设置ID,RelativeContainer不设置默认id为“ __ container __ ”,别的子元素的ID通过id属性设置。不设置id的组件能表现,但是不能被其他子组件作为锚点
  3、 对齐方式

align值对应摆列值
程度方向:

HorizontalAlign.Start 左
HorizontalAlign.Center 中
align:HorizontalAlign.End 右
垂直方向

VerticalAlign.Top 上
VerticalAlign.Center 中
VerticalAlign.Bottom 下
4、 利用示例

示例1:

  1. @Entry
  2. @Component
  3. struct Index {
  4.   build() {
  5.     RelativeContainer() {
  6.       Button('按钮').alignRules({
  7.         left: { anchor: '__container__', align: HorizontalAlign.Start },
  8.         bottom: { anchor: '__container__', align: VerticalAlign.Bottom } })
  9.     }.width('100%')
  10.     .height('100%')
  11.   }
  12. }
复制代码
  阐明:按钮程度方向基于父容器左边对齐,垂直方向基于父容器底部对齐
  运行效果:

示例2:

  1. @Entry
  2. @Component
  3. struct Index {
  4.   build() {
  5.     RelativeContainer() {
  6.       Button('按钮').alignRules({
  7.         right: { anchor: '__container__', align: HorizontalAlign.Center },
  8.         top: { anchor: '__container__', align: VerticalAlign.Center } })
  9.         .width(100).height(150)
  10.     }.width('100%')
  11.     .height('100%')
  12.   }
  13. }
复制代码
  阐明:按钮的右边与父容器程度方向中央对齐,顶部与父容器纵向中央对齐
  运行效果:

示例3:

  1. @Entry
  2. @Component
  3. struct Index {
  4.   build() {
  5.     RelativeContainer() {
  6.       Column() {
  7.         Text('矩形')
  8.       }
  9.       .width(100)
  10.       .height(50)
  11.       .backgroundColor('#ff22f2')
  12.       .margin({
  13.         top: 80,
  14.         left: 100
  15.       })
  16.       .id('rect')
  17.       Button('按钮').alignRules({
  18.         left: { anchor: 'rect', align: HorizontalAlign.End },
  19.         top: { anchor: 'rect', align: VerticalAlign.Bottom }
  20.       })
  21.         .width(100).height(150)
  22.     }.width('100%')
  23.     .height('100%')
  24.   }
  25. }
复制代码
  阐明:按钮左边与矩形右边对齐,按钮顶部与按钮底部对齐
  运行效果:

示例4:

  1. @Entry
  2. @Component
  3. struct Index {
  4.   build() {
  5.     RelativeContainer() {
  6.       Column() {
  7.         Text('矩形')
  8.       }
  9.       .width(100)
  10.       .height(50)
  11.       .backgroundColor('#ff22f2')
  12.       .margin({
  13.         top: 80,
  14.         left: 100
  15.       })
  16.       .id('rect')
  17.       Button('按钮').alignRules({
  18.         left: { anchor: 'rect', align: HorizontalAlign.End },
  19.         top: { anchor: 'rect', align: VerticalAlign.Bottom }
  20.       }).id('button').width(100).height(150)
  21.       Button('按钮2').alignRules({
  22.         right: { anchor: 'button', align: HorizontalAlign.Start },
  23.         top: { anchor: 'button', align: VerticalAlign.Bottom }
  24.       }).width(100).height(150)
  25.     }.width('100%')
  26.     .height('100%')
  27.   }
  28. }
复制代码
  阐明:
按钮1左边与矩形右边对齐,按钮1顶部与按钮底部对齐
按钮2右边与按钮1左边对齐,按钮2顶部与按钮1底部对齐
  运行效果:

示例5:

  1. @Entry
  2. @Component
  3. struct Index {
  4.   build() {
  5.     RelativeContainer() {
  6.       Button('按钮').alignRules({
  7.         right: { anchor: '__container__', align: HorizontalAlign.End },
  8.         top: { anchor: '__container__', align: VerticalAlign.Top },
  9.         bottom: { anchor: '__container__', align: VerticalAlign.Bottom },
  10.       })
  11.     }
  12.   }
  13. }
  14. 说明:通过设置按钮顶部贴父容器顶部,底部贴父容器底部,按钮高度自动填满父元素
复制代码
运行效果:

(5)相对结构2(offset)

   通用属性offset的作用跟css相对结构是一样的,相对于自身的位置举行偏移,不影响父容器结构。
  根本语法:
  1. 组件.offset({
  2.          x:10,
  3.          y:10
  4.        })
  5. 组件.offset({
  6.          x:-10,
  7.          y:-10
  8.        })
  9. 组件.offset({
  10.          x:'10px',
  11.          y:'10vp'
  12.        })
  13.       
  14. 组件.offset({
  15.          x:"20%",
  16.          y:10
  17.        })
复制代码
阐明:
1、x表现程度方向偏移量,y表现纵向方法偏移量,值单位默认vp,也可以字符串自带单位。
2、x为负值表现向左偏移,正值向右偏移,同理y为负值表现向上偏移,正值向下偏移。
3、值也支持%字符串,百分比相对的是父容器的宽或高,比方x:50%,则组件向右偏移父容器宽度的50%
示例

按钮初始位置在屏幕左上角
  1. @Entry
  2. @Component
  3. struct Index {
  4.   build() {
  5.     Column(){
  6.        Button('按钮')
  7.     }.width('100%').height(500).backgroundColor(Color.Green).alignItems(HorizontalAlign.Start)
  8.   }
  9. }
复制代码

示例1:

  1. @Entry
  2. @Component
  3. struct Index {
  4.   build() {
  5.     Column(){
  6.        Button('按钮').offset({
  7.          x:100,
  8.          y:100
  9.        })
  10.     }.width('100%').height(500).backgroundColor(Color.Green).alignItems(HorizontalAlign.Start)
  11.   }
  12. }
复制代码
运行效果:

示例2:

  1. @Entry
  2. @Component
  3. struct Index {
  4.   build() {
  5.     Column(){
  6.        Button('按钮').offset({
  7.          x:'50%',
  8.          y:0
  9.        })
  10.     }.width('100%').height(500).backgroundColor(Color.Green).alignItems(HorizontalAlign.Start)
  11.   }
  12. }
复制代码
运行效果:

(6)绝对结构(position)

   通用属性position的作用跟css绝对结构是一样的,子组件相对父容器确定位置,当父容器为Row/Column/Flex时,设置position的子组件不占位,不影响其他兄门生组件正常结构。
  根本语法:
  1. 组件.position({
  2.           x:10,
  3.           y:10
  4.        })
  5. 组件.position({
  6.           x:-10,
  7.          y:-10
  8.        })
  9. 组件.position({
  10.           x:"50%",
  11.          y:"10px"
  12.        })
  13. 组件.position({
  14.           left:10,
  15.           top:10
  16.        })
  17. 组件.position({
  18.           right:10,
  19.           bottom:10
  20.        })
复制代码
阐明:
1、入参范例既支持Position(x\y)范例也支持Edges(top\bottom\left\right)范例
2、和offset一样值支持字符串单位、百分比、数字范例,默认单位vp,支持正负值。
3、Edges(top\bottom\left\right)范例用法跟css根本划一,top相对父容器顶部隔断,bottom相对父容器底部隔断,left相对父容器左边隔断,right相对父容器右边隔断,通过边距来确定组件相对于父组件的位置。只需设置2个方向就能确定位置,好比top+left大概bottom+right,同时设置top和bottom,仅top收效;同时设置left和right,仅left收效
4、Position(x\y)范例的x\y实际等同于Edges left\top,x=left,y=top
5、与css差异的是鸿蒙的绝对结构相对父容器起始位置必要扣去padding部门,相当于ie盒子模子内容部门。
示例1:

  1. @Entry
  2. @Component
  3. struct Index {
  4.   build() {
  5.     Column(){
  6.        Button('按钮').position({
  7.          x:'0',
  8.          y:'500px'
  9.        })
  10.     }.width('100%').height(500).backgroundColor(Color.Green).alignItems(HorizontalAlign.Start)
  11.   }
  12. }
复制代码
运行效果:

示例2:

  1. @Entry
  2. @Component
  3. struct Index {
  4.   build() {
  5.     Column(){
  6.        Button('按钮').position({
  7.          left:0,
  8.         bottom:-25
  9.        }).width(100).height(50)
  10.     }.width('100%').height(500).backgroundColor(Color.Green).alignItems(HorizontalAlign.Start)
  11.   }
  12. }
复制代码
运行效果:

   阐明:按钮底部和父容器底部相距-25vp,也即按钮向下平移了25vp即是按钮自身高度一半
  示例3:

  1. @Entry
  2. @Component
  3. struct Index {
  4.   build() {
  5.     Column(){
  6.        Button('按钮').position({
  7.          right:0,
  8.         bottom:0
  9.        }).width(100).height(50)
  10.     }.width('100%').height(500).backgroundColor(Color.Green).alignItems(HorizontalAlign.Start)
  11.   }
  12. }
复制代码
运行效果:

   阐明:按钮和父容器右边和底部贴合,隔断为0,以是按钮位置在父容器右下角
  示例4:

   子组件位于父组件程度垂直居中通用方法:
  1. @Entry
  2. @Component
  3. struct Index {
  4.   build() {
  5.     Column() {
  6.       Button('按钮').position({
  7.         left: '50%',
  8.         top: '50%'
  9.       }).translate({
  10.         x: '-50%',
  11.         y: '-50%'
  12.       }).width(100).height(50)
  13.     }.width('100%').height(500).backgroundColor(Color.Green).alignItems(HorizontalAlign.Start)
  14.   }
  15. }
复制代码
运行效果:

   阐明:position+translate可以实现恣意子组件程度垂直居中,position分别设置了50%此时子组件隔断父组件上边和左边都为父组件宽高一半隔断,此时子组件的左上角点刚幸亏父组件正中央点。想要让子组件居中只需让子组件的中央点和父组件中央重叠,把子组件向左和向上平移自身一半宽高即可,可以用通用属性translate举行平移
  1. .translate({
  2.         x: '-50%',
  3.         y: '-50%'
  4.       }
复制代码
此处百分比相对组件自己宽高,负值表现往上或往左平移
示例5:

   父容器带padding环境
  1. @Entry
  2. @Component
  3. struct Index {
  4.   build() {
  5.     Column(){
  6.       Button('按钮').position({
  7.         top:0,
  8.         left:0
  9.       }).width(100).height(50)
  10.     }.width('100%').height(500).backgroundColor(Color.Green).padding(50)
  11.   }
  12. }
复制代码
运行效果:

   阐明:从运行效果可以看出相对父容器起始位置必要扣除父容器的padding部门
  
二、结构中的渲染控制

   在vue中可以利用v-if,v-else条件语句控制子组件是否渲染,也可以通过v-for循环渲染多个子组件。鸿蒙也有类似用法分别为if/else和ForEach
  1. if/else

结构渲染条件控制语句
示例:
  1. @Entry
  2. @Component
  3. struct Index {
  4.   @State type:number=0
  5.   build() {
  6.     Column() {
  7.         //显示文本
  8.        if(this.type==0){
  9.          Text('文本')
  10.        }
  11.        //显示按钮
  12.        else if(this.type==1){
  13.          Button('按钮')
  14.        }
  15.        //显示文本输入框
  16.        else{
  17.          TextInput({placeholder:'文本输入框'})
  18.        }
  19.        Button('改变类型').onClick(()=>{
  20.           this.type=++this.type%3
  21.        }).margin({top:100})
  22.     }.width('100%').height('100%').justifyContent(FlexAlign.Center).alignItems(HorizontalAlign.Center)
  23.   }
  24. }
复制代码
运行效果

阐明:通过改变状态变量type动态控制表现的子组件,
   必要注意if else内部只能写入子组件不能写入arkTs语法,好比打印信息console.log()就会报错。
  2. ForEach

结构循环渲染控制语句
语法:
  1. ForEach(list:Array<ESObject>,fn:(item:ESObject,index:number)=>void,fn:(item:ESObject,index:number)=>string)
  2. 其中:item为数组当前元素值,index为循环的索引
复制代码
  ForEach有三个入参,第一个入参是数据源数组,第二个入参是个函数,内部添加要循环渲染的子组件,第三个参数是函数返回唯一标识key,第三个入参类似vue v-for 的key作用为了制止重复渲染导致的额外开销进步性能,以是返回的key必须唯一值,否则会非常
  示例1:

  1. @Entry
  2. @Component
  3. struct Index {
  4.   @State list: number[] = [1, 2, 3, 4, 5, 6]
  5.   build() {
  6.     Column() {
  7.       ForEach(this.list, (item: number, index: number) => {
  8.       //需要循环渲染的子组件
  9.         Row() {
  10.           Text(`内容为${item},第${index}行`)
  11.         }.padding(15).justifyContent(FlexAlign.Start).width('100%')
  12.         //
  13.       }, (item: number, index: number) => index + '')
  14.     }.width('100%').height('100%')
  15.   }
  16. }
复制代码
运行效果:

示例2:

List和ListItem体系组件(列表)利用
  1. @Entry
  2. @Component
  3. struct Index {
  4.   @State list: number[] = [1, 2, 3, 4, 5, 6]
  5.   build() {
  6.     List() {
  7.       ForEach(this.list, (item: number, index: number) => {
  8.         ListItem() {
  9.            Text(`${index}`)
  10.         }.height(60).width('100%').border({
  11.           width:1,
  12.           color:"#f2f2f2"
  13.         })
  14.       }, (item: number, index: number) => index + '')
  15.     }
  16.   }
  17. }
复制代码
运行效果:

ps:如果列表数据非常多加载卡顿也可以利用懒加载LazyForEach,请看官网文档LazyForEach:数据懒加载这里不再先容。

三、项目开辟过程中结构像素单位的选择

1、像素单位先容

   鸿蒙结构像素单位支持px、vp、lpx、fp4种单位,此中fp紧张用来设置字体巨细,数值不写单位默认是vp
  px

屏幕物理像素单位。
vp

假造像素单位类似安卓内里的dp,VP是根据屏幕的‌PPI(每英寸像素点数)举行换算的。详细换算公式为:vp = (px * 160) / PPI,在480PPI手机上1vp=3px,简而言之,vp是屏幕密度相干像素,根据屏幕像素密度转换为屏幕物理像素。
fp

字体像素,与vp类似实用屏幕密度变革,区别在于fp会随体系字体巨细设置变革。即默认环境下 1 fp = 1vp。如果用户在设置中选择了更大的字体,字体的实际表现巨细就会在 vp 的根本上乘以 scale 系数,即 1 fp = 1 vp * scale
lpx

视窗逻辑像素单位,lpx单位为实际屏幕宽度与逻辑宽度(通过designWidth设置)的比值,designWidth默认值为720。当designWidth为720时,在实际宽度为1440物理像素的屏幕上,1lpx为2px巨细。
   lpx类似css内里的rem大概小步伐内里的rpx单位,以屏幕宽度为基准一种比值逻辑单位
  2、像素单位之间的转换

   鸿蒙sdk已自带单位换算方法,直接调用即可,如下:
  

示例:
  1.     //vp转px单位
  2.     vp2px(20)
  3.     //px转lpx
  4.     px2lpx(20)
  5.     //px转vp
  6.     px2vp(20)
  7.     //vp转lpx,没有直接转的函数,所以需要先把vp转px,在把px转lpx
  8.     px2lpx(vp2px(20))
复制代码
3、实际开辟单位的选择

实际开辟中我们必要适配全部装备, 选择某个单位使得结构在全部装备表现比例一样。从上面先容看,vp和lpx都能满意我们的需求,只管vp是默认单位也是官方保举利用的单位,但在实际开辟中我们拿到计划稿尺寸跟vp换算复杂无法直接盘算出来,在1440屏幕宽度的装备上1vp约莫=3px,如果从计划稿读取尺寸为285px,换算为vp=285/3,每个地方都要如许默算就比力费劲了。固然你也可以选择用px2vp(285),但是每个地方都如许写代码显得囊肿。以是保举利用lpx作为开辟单位。如果你是web开辟出身,你完全可以把lpx当做rem单位明确,鸿蒙的lpx支持我们自界说基准宽(designWidth),以是我们能轻松通过自界说designWidth值使得计划稿1px=1lpx。如许就不必要复杂换算,计划稿读取值多少就写多少。
lpx基准宽(designWidth)设置:

路径: entry/src/main/resources/base/profile/main_pages.json,添加:
  1. "window": {
  2.     "designWidth": 750
  3.   }
复制代码

拿到的计划稿宽多少,designWidth值就设置多少,好比计划稿是1080x1920,designWidth设置为1080。
如许设置完毕1px=1lpx
验证:
  1. @Entry
  2. @Component
  3. struct Index {
  4.   build() {
  5.     Column() {
  6.       Text('750lpx').width('750lpx').height('100lpx').backgroundColor(Color.Red)
  7.       Text('730lpx').width('730lpx').height('100lpx').backgroundColor(Color.Yellow)
  8.       Text('375lpx').width('375lpx').height('100lpx').backgroundColor(Color.Blue)
  9.     }.alignItems(HorizontalAlign.Start)
  10.   }
  11. }
复制代码
运行效果:

从运行效果可以看出当宽设置为750lpx刚好铺满屏幕,730lpx有一点间隙,375lpx占屏幕一半,符合预期效果,验证乐成。
四、竣事

竣事前照旧趁便提下鸿蒙结构里有个很常用的通用属性跟css定名长得最不一样,大概很多人一开始都找不到。
css中有个:overflow: hidden 表现子元素超出父元素范围的部门会被隐蔽
对应的鸿蒙写法为:clip(true)
示例
未加clip(true)效果
  1. @Entry
  2. @Component
  3. struct Index {
  4.   build() {
  5.     Stack() {
  6.       Column() {
  7.         Button('按钮').width(350).height(100)
  8.       }
  9.       .width(200)
  10.       .height(200)
  11.       .backgroundColor(Color.Red)
  12.       .justifyContent(FlexAlign.Center)
  13.      
  14.     }.height('100%').width('100%')
  15.   }
  16. }
复制代码

加clip(true)效果
  1. @Entry
  2. @Component
  3. struct Index {
  4.   build() {
  5.     Stack() {
  6.       Column() {
  7.         Button('按钮').width(350).height(100)
  8.       }
  9.       .width(200)
  10.       .height(200)
  11.       .backgroundColor(Color.Red)
  12.       .justifyContent(FlexAlign.Center)
  13.       .clip(true)
  14.     }.height('100%').width('100%')
  15.   }
  16. }
复制代码


免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!qidao123.com:ToB企服之家,中国第一个企服评测及软件市场,开放入驻,技术点评得现金

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

×
回复

使用道具 举报

登录后关闭弹窗

登录参与点评抽奖  加入IT实名职场社区
去登录
快速回复 返回顶部 返回列表