了解更多开源内容请访问:开源基础软件社区https://ost.51cto.com。前言通过参加《HarmonyOSArkUI入门训练营-健康生活实战》,了解并学习了声明式UI开发框架和组件使用。本篇文章是作者收官之作中自定义弹窗组件的一小部分分享。概述这是一款运动记录应用,主要用于管理健康记录运动。您可以添加运动信息,包括运动名称、运动时长,并自动计算燃烧的卡路里。您可以在记录页面查看已添加的运动记录。自定义弹窗组件运行效果图如下:正文1.整体布局设置弹窗内容从效果图布局。顶部是“取消”和“确定”两个按钮和一个弹窗标题,中间部分是运动项目的数据(包括图片,名称,单位消耗的卡路里,时间输入框和自动计算的总值计算),最下面是一个简单的输入设备(0-9的输入和删除)。三部分纵向排列,顶部横向排列,底部的输入设备采用网格布局。自定义弹窗组件要用**@CustomDialog**装饰。我将弹出组件命名为Record,其基本布局代码框架如下:@CustomDialogstructRecord{privatecontroller:CustomDialogController@Statetime:string='0'@Statesum:number=0privatetitle:string='AddSports的privatesportsItem:SportsData//自定义类//其他定义的变量...//运动数据项的布局@BuilderRecordItem(image:Resource,name:string,value:number){}//输入的布局device@BuildervalueInput(){}//弹窗总布局build(){Column(){Row(){Button('Cancel').fontSize(16).fontColor('#3ECF69').width(70).height(25).backgroundColor(Color.White).onClick(()=>{this.controller.close()})Blank().flexGrow(1)Text(this.title).fontSize(22).fontWeight(400).width(100)Blank().flexGrow(1)Button('Confirm').fontSize(16).fontColor('#3ECF69').width(70).height(25).backgroundColor(Color.White).onClick(()=>{})}.width('100%').height(50)Divider().width('100%').vertical(false).strokeWidth(0.5)this.RecordItem(this.sportsItem.image,this.sportsItem.name,this.sportsItem.value)Divider().width('100%').vertical(false).strokeWidth(0.5)行(){Blank().flexGrow(100)Row(){Text(this.time).fontColor('#E14843').fontSize(28).margin({right:3})Text('minute').fontSize(17)}.width(100)Blank().flexGrow(1)文本(this.sum+'kcal').fontColor(Color.Gray).fontSize(17).width(100).textAlign(TextAlign.End).padding(5)}.width('100%').margin({top:12,bottom:12})Divider().width('100%').vertical(false).strokeWidth(0.5)这个。valueInput()//Inputdevice}.width('82%')}}2.子布局设置和点击事件设置由于原demo中motion数据项的数据是基于点击的列表项,参数传递来显示相应的图片和名称,读者可以使用静态数据来调试这个自定义弹窗组件代码部分如下:@BuilderRecordItem(image:Resource,name:string,value:number){Flex({direction:FlexDirection.Column,justifyContent:FlexAlign.Center,alignItems:ItemAlign.Center}){Image(image.width(60).height(60).borderRadius(30).objectFit(ImageFit.Contain).backgroundColor('#ffffff').margin(5)文本(名称).fontSize(17).margin(5)Row({space:6}){Text(value.toString()).fontColor('#EC7143').fontSize(19)Text('kcal/60分钟').fontColor(Color.Gray).fontSize(17)}.margin(5)}.height(170).backgroundColor('#F5F5F5').width('100%')}对于输入部分,因为“删除记录”按钮在“添加记录”时没有响应,so定义变量mode来区分添加记录和修改记录。privatemode:number=0//0:添加,1:修改privateValueinput:any[]=['1','2','3','4','5','6','7','8','9','deleterecord','0',$r('app.media.Back')]然后定义一个4行3列的网格布局,使用ForEach循环渲染布局,根据按键类型定义对应的点击事件。如果是字符串类型,长度为1,则为输入(即字符串拼接),输入范围定义为0-999。每次单击时都会调用Calculate()。这是一个计算总值并实时显示计算结果的功能。如果key类型是图片,会执行回删的点击事件,也会调用calculate()。当您点击“删除记录”时,会弹出一个确认窗口。代码如下:calculate(){if(this.time.length!=0){this.sum=Math.round(parseInt(this.time)*this.sportsItem.value/60)}else{this.sum=0}}@BuildervalueInput(){Column(){Grid(){ForEach(this.Valueinput,(item:any)=>{GridItem(){if(typeof(item)=='string'){Text(item).fontSize(20).fontWeight(500).width('100%').height('100%').textAlign(TextAlign.Center).onClick(()=>{if(item.length<2){if(this.time=='0'){this.time=item}elseif(parseInt(this.time)<999&&parseInt(this.time+item)<999){this.time=this.time+item}else{this.time='999'}this.calculate()}else{if(this.mode==1){AlertDialog.show({message:'你确定要删除这条运动记录吗?',primaryButton:{value:'Cancel',action:()=>{}},secondaryButton:{value:'OK',action:()=>{//删除逻辑...this.controller.close()}},cancel:()=>{}})}}})}elseif(typeof(item)=='object'){Image(item).width(20).aspectRatio(1).objectFit(ImageFit.Contain).onClick(()=>{if(this.time.length>1){this.time=this.time.substring(0,this.time.length-1)}elseif(this.time.length==1){this.time='0'}this.calculate()})}}})}.backgroundColor(Color.White).columnsTemplate('1fr1fr1fr').rowsTemplate('1fr1fr1fr1fr').columnsGap(0).rowsGap(0).width('100%').height('35%')}}3.整体布局的点击事件和调用自定义弹窗组件1.确认按钮的点击事件涉及到全局变量等其他组件的代码,所以笔者简单的拿业务逻辑的实现代码如下:Button('Confirm').fontSize(16).fontColor('#3ECF69').width(70).height(25).backgroundColor(Color.White).onClick(()=>{if(this.time=='0'){prompt.showToast({message:'输入不能为零',duration:1000})}else{if(this.mode==0){//添加实现记录的代码,作者是通过将数据压入数组变量来实现的。}elseif(this.mode==1){//修改(更新)记录的实现代码,作者是通过更新数组来实现的}this.controller.close()}})}.width('100%').height(50)2.调用自定义弹窗组件主要代码如下:@ComponentexportstructSportsGridItem{privatesportsItem:SportsDataprivatecontroller:CustomDialogControlleraboutToAppear(){this.controller=newCustomDialogController({builder:Record({sportsItem:this.sportsItem}),alignment:DialogAlignment.Center})}结论上面就是这个小分享!了解更多开源知识,请访问:开源基础软件社区https://ost.51cto.com。
