2、HarmonyOS鸿蒙开发--ArkUI界面开发基础

ArkUI基础

组件:ArkUI构建页面的最小单元
组件分类:容器组件(column,row),基础组件
布局思路:先排版,放内容,后美化
注意:build是容器组件,且只能有一个根元素(不可并列两个row/column)

1. 组件的属性与方法

组件的属性和方法可以用来美化组件的外观效果
常见的属性如下:

组件(){}
  .width(20)  //设置组件宽度,也可设置为百分百
  .height(200)//设置组件高度
  .backgroundColor(Color.pink)//设置组件的背景颜色
  .fontSize//设置组件字体大小
  .fontWeight(FontWeight.Bold) //设置组件字体粗细
  .fontColor('#666') //色值是通用的

色值的写法:
1、枚举颜色:Color.Red
2、#开头的16进制,如:#8fbce7

属性:设置文字溢出省略号

Text()    
  //设置文字溢出的符号
  .textOverflow({overflow:TextOverflow.Ellipsis})
  .maxLines(2) //设置最大行数
  .lineHeight(20)//设置文字行高

示例:

@Entry
@Component
struct Index{
build(){
    Column(){
      Text('HarmonyOS开发初体验')
        .width('100%')
        .lineHeight(50)
        .fontSize(40)
        .fontWeight(FontWeight.Bold)
      Text('HarmonyOS开发初体验')
        .width('100%')
        .lineHeight(24)
        .textOverflow({overflow:TextOverflow.Ellipsis})//文字溢出省略号
        .maxLines(2)//必须配合maxLines才有效果
    }  
  }
}

组件:输入框:TextInput().属性方法()
组件:按钮:Button('按钮名称')

Column(){
 TextInput({placeholder:'请输入用户名'}) //placeholder 占位提示文本
    .type(InputTpe.Normal)
  TextInput({placeholder:'请输入密码'})
    .type(InputTpe.Password)
  Button('登录')
}

布局元素的组成


属性:内边距padding,在组件内添加间距,拉开内容与组件边缘之间的距离

Text('HarmonyOS开发初体验')
  .padding(20)//四个方向(上下左右)的内边距都为20
Text('HarmonyOS开发初体验01')
  .padding({
    top:20
    right:30
    left:50
    bottom:60  
  //分别设置上下左右的内边距
})

属性:外边距margin,再组件外添加间距,拉开两个组件之间的距离

Text('HarmonyOS开发初体验')
  .margin(20)//四个方向(上下左右)的外边距都为20
Text('HarmonyOS开发初体验01')
  .margin({
    top:20
    right:30
    left:50
    bottom:60  
  //分别设置上下左右的外边距

属性:边框border,给组件添加边界,进行装饰美化

Text('边框')
  .border({
    width:1 //设置边框宽度
    color:'#23158' //设置边框颜色
    style:BorderStyle.Solid //设置边框样式(实线,虚线)
    //四个方向设置一致
})

Text('HarmonyOS开发初体验01')
  .border({
    width:{
      left:1,
      right:2 
      },
    color:{
      left:Color.Red,
      right:Color.Blue
      },
    style:{
      left:BorderStyle.Dashed,
      right:BorderStyle.Dotted
      }
  //分别设置上下左右的边框

属性:圆角.borderRadius(参数)

Text('圆角')
  .borderRadius(20)//四个方向(上下左右)的圆角都为20

Text('圆角01')
  .margin({
    topleft:20
    topright:30
    bottomLeft:50
    bottomRight:60  
  //分别设置上下左右的圆角

补充:
1、特殊圆角--正圆:设置为宽/高的一半

Text('圆角')
  .width(20)
  .height(20)
  .borderRadius(10)//设置为宽/高的一半

2、胶囊按钮:宽度大,高度小,设置为高的一半

Text('圆角')
  .width(200)
  .height(20)
  .borderRadius(10) //设置为高的一半

属性:背景图片
1、添加背景图:backgrounImage($r('图片路径'),ImageRepeat.XY), ImageRepeat代表是否平铺
2、设置背景图片的位置:backgrounImagePosition(坐标对象 或 枚举),调节背景图在组件中的显示位置,默认显示为左上角

Text()
  .backgrounImage($r('app.media.flower'))
  .backgrounImagePosition({x:100,y:200}) // 设置具体位置
  .backgrounImagePosition(Alignment.Center) //Center居中, BottomEnd 右下角,TopStart 左顶点 TopEnd 有顶点

注意:背景定位,单位问题:
背景定位默认单位 px,是实际的物理像素点,设备出厂就定好了,是分辨率的单位
宽高默认单位 vp ,虚拟像素,相对于不同设备会自动转换,保证不同设备视觉一致,推荐用该单位。
把px转为vp的函数:vp2px(数值)

3、设置背景图片的尺寸:backgrounImageSize(宽高对象 或 枚举)

Text()
  .backgrounImage($r('app.media.flower'))
  .backgrounImageSize({width:100,height:200})  // 设置具体宽高
  .backgrounImageSize(ImageSize.Cover) 
//Cover 等比例缩放背景图--到图片完全覆盖组件(图片展示可能不完整,但不会留白)
//Contain 等比例缩放背景图--当高/宽与组件尺寸相同时,停止缩放(图片展示完整,但可能会留白)
//Auto 默认原图尺寸

2.页面布局

2.1 线性布局

线性布局:通过容器组件column和row创建
column:子元素垂直方向排列,如:三, 横与横是垂直排列
row:子元素水平方向排列,如,川 ,竖与竖是水平排列
1、属性1: 排布主方向(主轴)的对齐方式.justifyContent(枚举FlexAlign),具体如下所示

justifyContent(枚举FlexAlign)  ctrl+p  cmd+p
1. Start 排布主方向,主抽起始位置对齐
2.Center   主抽居中对齐
3.End  主抽结束位置对齐
4.SpaceBetween   贴边显示,中间元素均匀分布间隙
5.SpaceAround 间隙环绕  靠边只有中间的一半间隙
6.SpaceEvenly 间隙均匀环绕,靠边也是完整的一份间隙

2、属性2:交叉抽的对齐方式alignItems(HorizontalAlign.End)
交叉轴在水平方向上:HorizontalAlign
交叉轴在垂直方向上:VerticalAlign


属性:自适应伸缩layoutWeight(number),设置了该属性的子元素,会按照权重进行分配主轴的空间

Row(){
   Text(左侧") 
    .layoutWeight(1)   //占用主轴的1份
    .height(50) 
    .backgroundColor (Color.Pink) 
  Text(右侧)   //自适应被分走1份后的主轴空间
    .width(70) 
    .height(50) 
    .backgroundColor(Color.Orange) 
}

绝对定位 : position
作用:控制组件的位置,可以实现层叠此效果
特点:参考父组件左上角进行偏移;绝对定位后的组件,不再占用自身原有位置
语法:.position(位置对象)
参数:{x:水平偏移量,y:垂直偏移量}

Text('文字内容')
  .position({
    x:50,
    y:50
})

示例:

struct Index{
build(){
  //position 绝对定位,控制组件的位置,可以实现层叠效果
    Column(){
      Text('大儿子').width(80).height(80).backgroundColor(Color.Green)
      Text('二儿子').width(80).height(80).backgroundColor(Color.Green)
        .position({x:50,y:50})
        .zIndex(3) // 实现层叠控制,数字越大,排列越靠上
      Text('三儿子').width(80).height(80).backgroundColor(Color.Green)
    }
  }
}

问题:使用position后,后面的组件明显层次更高,会盖住前面的组件
解决办法:
1、改变组件的结构(前后顺序)
2、不改变组件结构的前提下,使用属性.zIndex(数字)实现,数字取值越大,显示层级越高(排列在最上层)如下:

2.2 层叠布局

层叠布局具有较强的组件层叠能力,一般使用在卡片层叠效果场景。
特点:层叠操作更简洁,编码效率高
语法:

Stack({
  //默认居中
  alignContent:Alignment.Center
}){
  Item1()
  Item2()
  Item3()
}

示例:

build(){
  Stack({
  alignContent:Alignment.end
}){
    Text('大儿子').width(250).weight(250).backgroundColor(Color.Green)
    Text('二儿子').width(250).weight(250).backgroundColor(Color.Orange)
    Text('三儿子').width(250).weight(250).backgroundColor(Color.Yellow)
}
}

补充:
1、字符串拼接:字符串和变量拼接

  • 使用 “+”拼接,适用与一个变量的拼接
let name:string = '小美'
console.log('简介信息','名字是'+name)
  • 使用${变量名}模版字符串(反引号)拼接,适用与多个变量的拼接
let name:string = '夏明'
let age:number = 15
console.log('简介信息',`姓名是${name},今年${age}岁了`)

2、类型转换:数字类型与字符串类型转换

  • 字符串转为数字
    (1)Number():字符串直接转为数字,转换失败返回NaN
    (2)parseInt():去掉小数部分转为数字,转换失败返回NaN
    (3)parseFloat():保留小数部分转为数字,转换失败返回NaN
    示例:
let money1:number =10000
let money2:string = '5000'
console.log('总工资',money1+mone2) //不转换直接相加,输出结果为10000500,直接拼接
onsole.log('总工资',money1+Number(mone2))// 输出结果15000,相加
  • 数字转为字符串
    数字不能直接展示,需要转换为字符串才能正常转换。
    number.toString():数字直接转为字符
    number.toFixed(): 四舍五入转为字符串,可设置保留几位小数,如number.toFixed(2)保留两位小数

3 组件的交互

  • 1.交互- 点击事件
    说明:组件被点击时触发的事件
    作用:监听(感知)用户的点击行为,进行操作
    语法:onclick((参数)=>{})
    示例:
Button('点我,显示弹框')
  .onclick(()=>{
    AlertDialog.show({
      message:'你好,这是一个弹框'
  })
})
  • 2.交互-状态管理
    普通变量:只需要初始化时渲染,后续将不会再刷新
    声明:let msg1:string = '你好'
    状态变量:需要装饰器,改变会引起UI的渲染刷新(必须设置类型和初始值)
    声明:@State msg1:string = '你好'

注意:定义在组件内的普通变量或状态变量,都需要通过this访问

// 普通变量,只能在初始化时渲染,后续变化了,也不能引起刷新
//状态变量,装饰器修饰,值变化时,会自动引起页面刷新
// 组件外的普通变量,不需要this,可直接访问
let myName:string = '大桥'

@Entry
@Component
struct Index{
  //组件内的普通变量  this.xx
  myAge:number = 18
  //组件内的状态变量 this.xxx
  @State myMsg:string='hello,大桥'
  build(){
    Column(){
      Text(myName)
        .onClick(()=>{
          myName='貂蝉'
            console.log('myName',myName)//控制台输出貂蝉,但界面任然显示大桥
})
      Text(this.myAge.tostring()).onClick(()=>{myAge=19
console.log('myAge',myAge)//控制台输出19,界面任然显示18
})
      Text(this.myMsg).onClick(()=>{myMsg='hello 貂蝉'
console.log('myMsg',myMsg)//控制台输出:hello,貂蝉,界面也显示:hello,貂蝉
})
      }
    }

  }

示例:按钮计算器


点击+,数字加1,点击- ,数字减1
实现思路:
1、装准状态变量:@State count:number = 1
2、注册点击事件
3、点击时,修改状态变量
4、状态变量改变,界面自动更新

@Entry
@Component
struct Index{
  @State count:number=1
  build(){
    Row(){
      Button('-')
        .onclink(()=>{
          this.count = this.count - 1
      Text(this.count.toString()).maegin(10)
      Button('+')
        .onclink(()=>{
          this.count = this.count + 1
     })
  }  
}

一元运算符:只有一个变量或一个数据,常见的一元运算符有++,--
后置写发:先复制后自增/自减
前置写发:先自增/自减再赋值
运算符的优先级:

数组的操作
查找:数组名[下标]数组名.length
修改:数组名[下标]=新值
新增:
结尾新增数组名.push(数据1,数据2)
开头新增数组名.unshift(数据1,数据2)
删除:数组名.pop()、数组名.shift()
任意位置增加或删除:数组名.splice(操作的起始位置,删除的个数,新增1,新增2)

let names:string[] = ['zhangsan','lisi','wangwu','wanger','mazi']

console.log('查找的姓名',names[0]) // 查找
console.log('数组长度',names.length) //数组长度
names[1]='jack'  //修改(通过下标)
console.log('数组信息',names)

//往开头新增 unshift(新增的值),返回操作后的数字长度names.unshift(新增值)
names.unshift('Tom')
console.log('数组信息',names)

//往末尾加
names.push('hailun','smith')
console.log('数组信息',names)

//删除数据
names.shift()  //从开头删除
names.pop()  //从末尾删除,会返回被删除的值

//任意位置添加和删除元素
//数组名.splice(操作的起始位置,删除几个,新增1,新增2)
names.splice(2,2) //从下标为2的元素开始删除,删除两个
names.splice(1,0,'彩虹','云儿')  //从下标为1开始操作,不删除元素,新增'彩虹','云儿'两个元素
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,053评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,527评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,779评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,685评论 1 276
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,699评论 5 366
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,609评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,989评论 3 396
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,654评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,890评论 1 298
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,634评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,716评论 1 330
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,394评论 4 319
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,976评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,950评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,191评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 44,849评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,458评论 2 342

推荐阅读更多精彩内容