一、鸿蒙应用界面开发
1. 弹性布局-Flex
- 语法
/* 弹性容器组件 Flex() 位置: Flex默认主轴水平往右,交叉轴垂直向下(类似Row) 语法: Flex(参数对象){ 子组件1, 子组件2, 子组件3 } 属性方法: direction::主轴方向 justifyContent:主轴对齐方式 alignItems:交叉轴对齐方式 wrap:布局换行 */
- 使用场景
// 如果是单行单列的建议使用线性布局 // 如果组件设计多行列的或者是不规则的布局建议使用弹性布局
- 主轴方向示例
/* direction参数: row:主轴水平往右 column:主轴垂直向下 RowReverse:主轴水平往左 */ // 示例:FlexDirection.ColumnReverse import { Filter } from '@ohos.arkui.advanced.Filter'; @Entry @Component struct Index { @State message: string = 'varin'; build() { Flex({ direction:FlexDirection.ColumnReverse }){ Text().width(50).height(50).backgroundColor("green") Text().width(50).height(50).backgroundColor("green").margin({top:2,bottom:2}) Text().width(50).height(50).backgroundColor("green") }.padding(10) } }
- 主轴方向对齐
/* justifyContent参数: FlexAlign.Start(默认) FlexAlign.Center(居中) FlexAlign.End(右对齐) FlexAlign.SpaceBetween (贴边对齐) FlexAlign.SpaceAround (间隙对齐) FlexAlign.SpaceEvenly (均匀对齐) */ // 示例 FlexAlign.SpaceEvenly @Entry @Component struct Index { @State message: string = 'varin'; build() { Flex({ direction:FlexDirection.Row, justifyContent:FlexAlign.SpaceEvenly }){ Text().width(50).height(50).backgroundColor("green") Text().width(50).height(50).backgroundColor("green") Text().width(50).height(50).backgroundColor("green") }.padding(10) } }
- 交叉轴对齐方式
/* alignItems枚举参数: ItemAlign.Auto ItemAlign.Start ItemAlign.Center ItemAlign.End ItemAlign.Baseline ItemAlign.Stretch (拉伸功能,类似于100%宽/高) */ // 示例 ItemAlign.Stretch import { Filter } from '@ohos.arkui.advanced.Filter'; @Entry @Component struct Index { @State message: string = 'varin'; build() { Flex({ direction:FlexDirection.Row, justifyContent:FlexAlign.Start, alignItems:ItemAlign.Stretch }){ Text().width(50).height(50).backgroundColor("green") Text().width(50).height(50).backgroundColor("green").margin({left:2,right:2}) Text().width(50).height(50).backgroundColor("green") }.padding(10).width("100%").height("100%") } }
2. 弹性布局-Flex换行(warp)
- 语法
/* 单行布局:FlexWrap.NoWrap 多行布局:FlexWrap.Wrap 语法: Flex({ wrap:FlexWrap.NoWrap/FlexWrap.Wrap }){ } */
- 实现效果
import { Filter } from '@ohos.arkui.advanced.Filter'; @Entry @Component struct Index { @State message: string = 'varin'; build() { Column(){ Text("阶段选择").fontWeight(700).margin({bottom:20}) Flex({ wrap:FlexWrap.Wrap }){ Text("ArkUI").padding(10).backgroundColor("#ffeceaea").textAlign(TextAlign.Center).margin(5) Text("ArkTS").padding(10).backgroundColor("#ffeceaea").textAlign(TextAlign.Center).margin(5) Text("界面开发").padding(10).backgroundColor("#ffeceaea").textAlign(TextAlign.Center).margin(5) Text("系统能力").padding(10).backgroundColor("#ffeceaea").textAlign(TextAlign.Center).margin(5) Text("权限控制").padding(10).backgroundColor("#ffeceaea").textAlign(TextAlign.Center).margin(5) Text("元服务").padding(10).backgroundColor("#ffeceaea").textAlign(TextAlign.Center).margin(5) } }.width("100%").height("100%").backgroundColor("#F5f5f5").padding(10).alignItems(HorizontalAlign.Start) } }
3. 绝对定位
- 语法
/* position 条件: 参照父组件x/y轴(0,0)进行偏移 绝对定位后的组件,不占用自身原有位置 语法: .position(位置对象) 位置对象:{x:值,y:值} */
- 实现效果
/* 扩展: 阴影属性:shadow 层级属性:zIndex 文字倾斜:fontStyle */ import { Filter } from '@ohos.arkui.advanced.Filter'; @Entry @Component struct Index { @State message: string = 'varin'; build() { Column(){ Column(){ Text("HOS").backgroundColor("#ff06eaea").position({}).zIndex(999).fontColor(Color.White) .fontWeight(500).width(50).textAlign(TextAlign.Center) .borderRadius({topLeft:10,bottomRight:10}).border({ width:3, style:BorderStyle.Solid, color:"#ffa4d6d6" }).fontStyle(FontStyle.Italic) Image($r("app.media.hw")).width("100%").height(200).borderRadius({ topLeft:10 }).margin({bottom:10}) Row(){ Image($r("app.media.user")).width(24).borderRadius(12).margin({left:10,right:10}) Text("HarmonyOS").fontWeight(700) }.width("100%") }.width(200).padding({bottom:10}).backgroundColor(Color.White).borderRadius({ topLeft:10 }).shadow({ color:Color.Black, offsetX:2, offsetY:2, radius:100 }) }.width("100%").height("100%").backgroundColor("#F5f5f5").padding(10).alignItems(HorizontalAlign.Center) } }
4. 层叠布局
- 简介:层叠布局具有较强的组件层叠能力
- 使用场景:卡片层叠效果
- 语法
Stack(){ 组件1 组件2 组件3 } // 对齐 alignContent:Alignment枚举类型(9种方位) // zindex(可以调层叠的关系)
- 实现效果
5. 案例-B站视频卡片
实现效果
@Entry @Component struct Index { @State message: string = 'varin'; build() { Column(){ Column(){ Stack({ alignContent:Alignment.BottomEnd }){ Image($r("app.media.bz_img")).borderRadius({topLeft:15,topRight:15}) Row(){ Image($r("app.media.bz_play")).width(20).fillColor(Color.White).margin({left:10,right:10}) Text("288万").fontColor(Color.White) Image($r("app.media.bz_msg")).width(20).fillColor(Color.White).margin({left:10,right:10}) Text("8655").fontColor(Color.White).layoutWeight(1) Text("4:33").fontColor(Color.White).margin({right:10}) }.width("100%").height(40) }.height(200) Text("【凤凰传奇新歌】欢迎来到国风统治区:唢呐一响神曲《铁衣》燃爆登场!").fontSize(18).textIndent(10).margin(10) .maxLines(2).textOverflow({overflow:TextOverflow.Ellipsis}) Row(){ Text("19万点赞").backgroundColor("#fffaf0eb").borderRadius(5) .fontColor("#ffefbda5").padding(3) Image($r("app.media.bz_more")).width(20).fillColor("#999") }.width("100%") .padding(10) .justifyContent(FlexAlign.SpaceBetween) }.width(320).backgroundColor(Color.White).borderRadius(15).shadow({ color:"#666", offsetX:1, offsetY:1, radius:80 }) }.width("100%").height("100%").backgroundColor("#f5f5f5").padding(10) } }
6. 案例-支付宝首页
实现效果
/* 扩展: 滚动组件:Scroll */ @Entry @Component struct Index { @State message: string = 'varin'; build() { Stack({alignContent:Alignment.Bottom}){ Stack({alignContent:Alignment.Top}){ // header_search Row(){ Column(){ Text("北京").fontColor(Color.White) Text("晴2℃").fontColor(Color.White).fontSize(12) Image($r("app.media.zfb_head_down")).width(12).fillColor(Color.White) .position({x:35,y:0}) } Row(){ Image($r("app.media.zfb_head_search")).width(20).fillColor("#999") Text("北京交通一卡通").margin({left:5}).layoutWeight(1).fontColor("#666") Text("搜索").margin({left:5}).fontColor("#5b73de") .border({width:{left:1},color:"#999"}).padding({left:10}).fontWeight(700) }.height(32).layoutWeight(1).backgroundColor(Color.White).borderRadius(5) .margin({right:12,left:25}).padding({left:5,right:5}) Image($r("app.media.zfb_head_plus")).width(30).fillColor(Color.White) }.width("100%").height(60).zIndex(999).padding({left:10,right:10}).backgroundColor("#5b73de") // body Scroll(){ Column(){ Row(){ Column(){ Image($r("app.media.zfb_top_scan")).width(36).fillColor(Color.White) Text("扫一扫").fontColor(Color.White) }.layoutWeight(1) Column(){ Image($r("app.media.zfb_top_pay")).width(36).fillColor(Color.White) Text("收付款").fontColor(Color.White) }.layoutWeight(1) Column(){ Image($r("app.media.zfb_top_travel")).width(36).fillColor(Color.White) Text("出行").fontColor(Color.White) }.layoutWeight(1) Column(){ Image($r("app.media.zfb_top_card")).width(36).fillColor(Color.White) Text("卡包").fontColor(Color.White) }.layoutWeight(1) }.width("100%").padding({top:5,bottom:15}) Column(){ Row(){ Column(){ Image($r("app.media.zfb_nav1")).width(28).fillColor(Color.White).margin({bottom:8}) .fillColor("#fff8873d") Text("滴滴出行").fontColor("#999").fontSize(12) }.layoutWeight(1) Column(){ Image($r("app.media.zfb_nav2")).width(28).fillColor(Color.White).margin({bottom:8}) .fillColor("#ff13adc1") Text("生活缴费").fontColor("#999").fontSize(12) }.layoutWeight(1) Column(){ Image($r("app.media.zfb_nav3")).width(28).fillColor(Color.White).margin({bottom:8}) .fillColor("#fff12745") Text("股票").fontColor("#999").fontSize(12) }.layoutWeight(1) Column(){ Image($r("app.media.zfb_nav4")).width(28).fillColor(Color.White).margin({bottom:8}) .fillColor("#ff069134") Text("蚂蚁森林").fontColor("#999").fontSize(12) }.layoutWeight(1) Column(){ Image($r("app.media.zfb_nav5")).width(28).fillColor(Color.White).margin({bottom:8}) .fillColor("#fff8873d") Text("手机充值").fontColor("#999").fontSize(12) }.layoutWeight(1) }.width("100%").padding(10) Row(){ Column(){ Image($r("app.media.zfb_nav6")).width(28).fillColor(Color.White).margin({bottom:8}) .fillColor("#fffa6401") Text("余额宝").fontColor("#999").fontSize(12) }.layoutWeight(1) Column(){ Image($r("app.media.zfb_nav7")).width(28).fillColor(Color.White).margin({bottom:8}) .fillColor("#ff13adc1") Text("花呗").fontColor("#999").fontSize(12) }.layoutWeight(1) Column(){ Image($r("app.media.zfb_nav8")).width(28).fillColor(Color.White).margin({bottom:8}) .fillColor("#fff1ae27") Text("飞猪旅行").fontColor("#999").fontSize(12) }.layoutWeight(1) Column(){ Image($r("app.media.zfb_nav9")).width(28).fillColor(Color.White).margin({bottom:8}) .fillColor("#ffde1443") Text("淘票票").fontColor("#999").fontSize(12) }.layoutWeight(1) Column(){ Image($r("app.media.zfb_nav10")).width(28).fillColor(Color.White).margin({bottom:8}) .fillColor("#ff44e2f1") Text("饿了么").fontColor("#999").fontSize(12) }.layoutWeight(1) }.width("100%").padding(10) Row(){ Column(){ Image($r("app.media.zfb_nav11")).width(28).fillColor(Color.White).margin({bottom:8}) .fillColor("#ff0c89ba") Text("读书听书").fontColor("#999").fontSize(12) }.layoutWeight(1) Column(){ Image($r("app.media.zfb_nav12")).width(28).fillColor(Color.White).margin({bottom:8}) .fillColor("#ff058798") Text("基金").fontColor("#999").fontSize(12) }.layoutWeight(1) Column(){ Image($r("app.media.zfb_nav13")).width(28).fillColor(Color.White).margin({bottom:8}) .fillColor("#ff429fef") Text("直播广场").fontColor("#999").fontSize(12) }.layoutWeight(1) Column(){ Image($r("app.media.zfb_nav14")).width(28).fillColor(Color.White).margin({bottom:8}) .fillColor("#ff2a7adb") Text("医疗健康").fontColor("#999").fontSize(12) }.layoutWeight(1) Column(){ Image($r("app.media.zfb_nav15_more")).width(28).fillColor(Color.White).margin({bottom:8}) .fillColor("#ff010809") Text("更多").fontColor("#999").fontSize(12) }.layoutWeight(1) }.width("100%").padding(10) Row({space:2}){ Image($r("app.media.zfb_pro_pic1")).height(200).layoutWeight(1) Image($r("app.media.zfb_pro_pic2")).height(200).layoutWeight(1) Image($r("app.media.zfb_pro_pic3")).height(200).layoutWeight(1) }.width("100%").padding({left:2,right:2,top:5,bottom:20}) Image($r("app.media.zfb_pro_list1")).width("100%").padding({left:2,right:2,top:0,bottom:10}) Image($r("app.media.zfb_pro_list2")).width("100%").padding({left:2,right:2,top:0,bottom:10}) }.backgroundColor("#f6f6f6").width("100%").borderRadius({ topLeft:20,topRight:20 }) }.width("100%").margin({top:60,bottom:60}) } }.width("100%").height("100%") // Tab_nav Row(){ Column(){ Image($r("app.media.zfb_tab_home")).width(35) }.layoutWeight(1) Column(){ Image($r("app.media.zfb_tab_money")).width(28) Text("理财").fontSize(12) }.layoutWeight(1) Column(){ Image($r("app.media.zfb_tab_life")).width(28) Text("生活").fontSize(12) }.layoutWeight(1) Column(){ Image($r("app.media.zfb_tab_chat")).width(28) Text("消息").fontSize(12) }.layoutWeight(1) Column(){ Image($r("app.media.zfb_tab_me")).width(28) Text("我的").fontSize(12) }.layoutWeight(1) }.width("100%").height(60).backgroundColor("#fbfcfe") }.backgroundColor("#5b73de").width("100%").height("100%") } }
二、ArkTs语法进阶
1. 字符串拼接
/* 加号可以将两个字符串拼接在一起,成为一个字符串 */ let name:string = "varin" console.log("Hello,"+name)
2. 模板字符串
- 作用:拼接字符串和变量
- 优势:更适合多个变量的拼接
// 示例 (反引号) let name:string = "varin" let date:string = "6月23日" console.log(`hello:${name},今天是${date}`)
3. 类型转换(数字和字符串)
- 字符串转数字
// Number() :直接转数字,不能存在非数字部分 // parseInt():去除小数部分,转数字 // parseFloat() 保留小数部分,转数字 /* 注意点:在使用console.log()函数时,第一个参数的数据类型需要是字符串 */ let num:string="1.2" console.log(`${Number(num)}`) console.log(`${parseInt(num)}`) console.log(`${parseFloat(num)}`)
- 数字转字符串
/* 方法一:加双引号 方法二:toString() 方法三:toFixed() :四舍五入转字符串,并可设置保留几位小数 */ let num=1.11 let str1:string = num+"" let str2:string=num.toString() let str3:string =num.toFixed(1) console.log(str1) console.log(typeof str1) console.log(str2) console.log(typeof str2) console.log(str3) console.log(typeof str3)
4. 运算符
- 算术运算符
// 包括加减乘除、取余(求模)等 /* + - * / % */ console.log("result>>>",1+1) console.log("result>>>",1-1) console.log("result>>>",1*1) console.log("result>>>",2/1) console.log("result>>>",3%2)
- 赋值运算符
- 一元运算符
/* 符号:++ -- 前置:先自增/减再赋值 后缀:先赋值在自增/减 */ let num1:number =1 console.log("result>>>>>>",num1++) // 1 console.log("result>>>>>>",++num1) // 3
- 比较运算符
/* 大于:> 大于等于:>= 小于:< 小于等于:<= 等于:== 不等:!= */
- 逻辑运算符
/* 与:&& 或:|| 非:! */ console.log("result>>>>>",1==1 && true) console.log("result>>>>>",true || 1) console.log("result>>>>>",!1)
5. 数组
- 数组定义
let names:string[] =['小明',"小红",'小兰']
- 数组查找
/* 查找 */ console.log("result>>>>",names) console.log("result>>>",names[0]) console.log("result>>>",names.length)
- 数组修改
names[0]="笑笑" console.log("result>>>>",names)
- 数组增加
console.log("result>>>>",names.unshift("小明","大明")) // 前加,添加完成后会返回数组的长度 console.log("result>>>>",names) console.log("result>>>>",names.push("小豆")) // 后加,添加完成后会返回数组的长度 console.log("result>>>>",names)
- 数组删除
console.log("result>>>>",names.shift() )// 前删,返回删除的项 console.log("result>>>>",names) console.log("result>>>>",names.pop() )// 后删,返回删除的项 console.log("result>>>>",names)
- 任意位置增加或删除
/* 语法:数组名.splice(起始位置,删除个数,新增元素1...) */ names.splice(0,1) ///删除第一个元素 console.log("result>>>>",names) names.splice(0,0,"a")// 从下标0新增元素,不删除元素, console.log("result>>>>",names) names.splice(0,1,"b")// 替换下标为0的元素 console.log("result>>>>",names)
6. 单分支-if
let num1:number = 1 if(num1==1){ // 条件为真执行以下语句 console.log("true") }
7. 多分支-(if-else)
// let num1:number = 2 if(num1==1){ // 满足条件执行 console.log("true") }else{// 不满足条件执行 console.log("false") }
8. 多分支-(if-else-else if)
// 满足什么条件执行什么语句 let num1:number = 2 if(num1==1){ console.log("1") } else if(num1==2){ console.log("2") } else{ console.log("3") }
9. 多分支-switch
// 匹配条件 let num1:number = 333 switch(num1){ case 1: console.log("1") break case 2: console.log("2") break default: console.log("error") }
10. 三元条件表达式
/* 语法: 条件?true:false */ 1==1?console.log("true"):console.log("false")
11. 循环语句-while
/* 条件循环:while 语法: while(true/false){ 语句 } */ let num:number = 1 while (num<=3){ console.log("result>>>",num) num++ } console.log("while循环结束")
12. 循环语句-for
/* 语法: for(初始值;条件;变化量){ 执行语句 } */ let num:number = 5 for(let i:number=0;num>=0;num--){ console.log("result>>>",num) }
13. 退出循环-(break/continue)
- break 退出循环
let num:number = 5 for(let i:number=0;num>=0;num--){ if(num==1){break} console.log("result>>>",num) } console.log("for循环结束")
- continue 跳出循环
let num:number = 5 for(let i:number=0;num>=0;num--){ if(num==1){continue} console.log("result>>>",num) } console.log("for循环结束")
14. 遍历数组
- 方法一:for
let names:string[] = ["小明","小红","小美","小东"] for (let i = 0; i < names.length; i++) { console.log("result=>>",names[i]) }
- 方法二:for of
let names:string[] = ["小明","小红","小美","小东"] for (let name of names) { console.log("result>>>>>",name) }
15. 对象数组
// 打印对象使用JSON.stringify() //构建对象接口 interface Person{ name:string, age:number } let persons:Person[]=[ {name:"小明",age:12}, {name:"小红",age:13}, {name:"小美",age:14}, {name:"小东",age:22}, ] // 打印下标为1的对象 console.log(JSON.stringify(persons[0]))
- 例:for of 打印所有对象
//构建对象接口 interface Person{ name:string, age:number } let persons:Person[]=[ {name:"小明",age:12}, {name:"小红",age:13}, {name:"小美",age:14}, {name:"小东",age:22}, ] // 打印下标为1的对象 for (let person of persons) { console.log(JSON.stringify(person)) }
三、界面交互功能
1. 点击事件
- 说明:组件被点击时触发的行为
- 作用:监听组件点击,从而反应对应操作
- 语法
onClick((参数)=>{ })
- 示例 :点击按钮,弹框信息
@Entry @Component struct Index { @State message: string = 'varin'; build() { Column(){ Button("点击一下").onClick((event: ClickEvent) => { AlertDialog.show({ message:'hello', }) console.log("点击一下") }) }.width("100%").height("100%").padding(10) } }
2. 状态管理
- 介绍:如果希望构建一个动态的、有交互的页面,就需要引入状态的概念。
- 状态变量:
@State - 普通变量和状态变量对比
/* 普通变量:在初始化时渲染,后续不会变化 状态变量:需要装饰器装饰,改变会引起UI的渲染刷新(需要设置类型和初始值) */
示例:点击按钮修改文本值
/* 结果: 虽然两个文本的值都得到了修改,但是在UI界面并不会重新渲染普通变量的值 注意点:在组件内说明的变量,调用时需要使用this,且定义变量时不需要let关键字修饰 */ @Entry @Component struct Index { @State text1:string ='varin1' text2:string = "varin2" build() { Column(){ Text(this.text1) Text(this.text2) Button("点击一下").onClick((event: ClickEvent) => { this.text1= "hello,varin1" this.text2= "hello,varin2" console.log(this.text1) console.log(this.text2) }) }.width("100%").height("100%").padding(10) } }
3. 运算符优先级
/* 高到低: 括号:() 一元:++,--,! 算术:*,/,%,+,- 比较:>,>=,<,<= 比较:==,!= 逻辑:&&=|| 赋值:= */
4. 案例-计数器
实现效果:点击加号,数字加1,点击减号,数字减1
@Entry @Component struct Index { @State num:number = 0 build() { Column(){ Row(){ Button("-").onClick(()=>{ if (this.num > 0) { this.num-=1 } }) Text(this.num.toString()).padding({left:10,right:10}) Button("+").onClick(()=>{ this.num+=1 }) }.width("100%") }.width("100%").height("100%").padding("10") } }
5. ForEach渲染控制
- 作用:循环渲染重复的组件
/* 语法: ForEach(数组,(数据中的值:数据类型,索引)=>{ 渲染组件并赋值 }) */
实现效果:
@Entry @Component struct Index { @State titles:string[] = [ "电子产品", "精品服饰", "母婴产品", "影音娱乐", "海外旅游", ] build() { Column(){ Column(){ ForEach(this.titles,(title:string,index)=>{ Text(title).width("100%").height(80).textAlign(TextAlign.Center).fontWeight(700).fontColor(Color.Orange).fontSize(24) }) } .width(200).height(80*this.titles.length).backgroundColor(Color.White).borderRadius(10) }.width("100%").height("100%").backgroundColor("#ffe3dfdf").padding(15) } }
6. 案例-卡片点赞
实现效果:能点赞和取消点赞
@Entry @Component struct Index { @State goodNum:number = 8899 @State goodColor:string="#999" @State goodState:boolean=false build() { Column(){ Column(){ Image($r("app.media.hos")).height(280).borderRadius({topLeft:10,topRight:10}) Text("华为鸿蒙系统是一款全新的面向全场景的分布式操作系统").lineHeight(30).fontSize(20).margin({left:10,right:10}).fontWeight(700) Row(){ Image($r("app.media.user")).width(30).borderRadius(15) Text("Varin").padding({left:10}).layoutWeight(1) Row(){ Image($r("app.media.ic_like")).padding({right:5}).width(25).fillColor(this.goodColor) Text(){ Span(this.goodNum.toString()) }.fontColor(this.goodColor) }.onClick(()=>{ if(!this.goodState){ this.goodNum+=1 this.goodColor="#ffef9898" this.goodState=true }else{ this.goodNum-=1 this.goodColor="#999" this.goodState=false } }) }.padding(10).width("100%") }.width(300).height(400).borderRadius(10).backgroundColor(Color.White) }.width("100%").height("100%").padding("10").backgroundColor("#fff3efef") } }
7. 案例-美团购物车
实现效果
@Entry @Component struct Index { @State productNum:number=0 @State price:number = 40.4 @State resultPrice:number =0.0 build() { Stack({alignContent:Alignment.Bottom}){ Scroll(){ Column(){ Row(){ Image($r("app.media.product1")).width("35%").borderRadius(10) Column(){ Text("冲销量100ml缤纷八果水果捞").height(20).width("100%") Text("含1份折扣商品").height(20).width("100%").fontSize(14).fontColor("#999") .lineHeight(20) Row(){ Text( ){ Span("¥").fontSize(14) Span("20.2").fontSize(20) Span("¥"+this.price).fontColor("#999").padding({left:5}).decoration({type:TextDecorationType.LineThrough}) }.fontColor(Color.Red).layoutWeight(1) Row(){ Text("-").layoutWeight(1).height("100%").textAlign(TextAlign.Center).onClick(()=>{ if(this.productNum>0){ this.productNum-- this.resultPrice-=20.2 }else{ this.resultPrice=0.00 } }) Text(this.productNum.toString()).height(20).layoutWeight(1).textAlign(TextAlign.Center).height("100%").border({ width:{left:1,right:1}, color:"#999" }) Text("+").layoutWeight(1).textAlign(TextAlign.Center).height("100%").onClick(()=>{ this.productNum++ this.resultPrice+=20.2 }) }.border({ width:1, color:"#999" }).borderRadius(5).height(25).width(90) }.height(40) }.layoutWeight(1).padding({left:10}) }.width("100%").height(80) }.padding({left:10,right:20,top:20}).width("100%").height("100%") } Row(){ Column(){ Text(){ Span("已选 "+this.productNum.toString()+" 件,").fontColor("#999") Span("合计:") Span("¥"+this.resultPrice.toFixed(2)).fontColor(Color.Red) }.width("100%").textAlign(TextAlign.End) Text("共减¥"+this.resultPrice.toFixed(2)).fontColor(Color.Red).width("100%").textAlign(TextAlign.End).fontSize(14).lineHeight(20) }.layoutWeight(1) Button("结算外卖").margin({left:10}).backgroundColor("#fff6ac6b").fontColor(Color.Black) }.width("100%").height(80).backgroundColor(Color.White).padding({left:10,right:20}) }.width("100%").height("100%").backgroundColor("#ffeae8e8") } }
8. 条件渲染案例-京东加购
实现效果:
@Entry @Component struct Index { @State isStock:boolean=true @State navHeight:number=60 build() { Stack({alignContent:Alignment.Bottom}){ Scroll(){ Column(){ Row(){ Button("有库存").onClick(()=>{ this.isStock=true this.navHeight=60 }) Button("无库存").onClick(()=>{ this.isStock=false this.navHeight=100 }).backgroundColor(Color.Red).margin({left:10}) } }.width("100%").height("100%").padding(10) } Column(){ if(this.isStock!=true){ Row(){ Image($r("app.media.ic_fly")).width(20).fillColor("#ffee8f37") Text("该商品暂时没有库存,看看类似商品吧").fontSize(10).margin({left:5}).fontColor("#ffee8f37").layoutWeight(1) Row(){ Image($r("app.media.ic_arrow_left")).width(15).fillColor("#ff944b06") }.width(16).height(16).borderRadius(8).backgroundColor("#ff777575").opacity(0.3).justifyContent(FlexAlign.Center) }.width("100%").height(40).backgroundColor("#ffffe8d3").padding(15) } Row(){ Row(){ Column(){ Image($r("app.media.ic_more")).width(20) Text("店铺").fontSize(12).lineHeight(20) }.layoutWeight(1) Column(){ Image($r("app.media.ic_more")).width(20) Text("客服").fontSize(12).lineHeight(20) }.layoutWeight(1) Column(){ Image($r("app.media.ic_more")).width(20) Text("购物车").fontSize(12).lineHeight(20) }.layoutWeight(1) }.layoutWeight(1) if(this.isStock==true){ Button("加入购物车").backgroundColor("#fff88940") Button("立即购买").backgroundColor("#ffe90404").margin({left:5}) }else{ Button("查看类似商品").backgroundColor("#fff88940") } }.width("100%").height(60).padding({left:15,right:15}) }.width("100%").height(this.navHeight).backgroundColor(Color.White) }.width("100%").height("100%").backgroundColor("#ffece7e7") } }