当前位置: 首页 > 科技观察

OpenHarmony-ArkUI(TS)开发下拉选择菜单

时间:2023-03-13 14:57:05 科技观察

了解更多开源请访问:开源基础软件社区https://ost.51cto.com前言鸿蒙3.0引入了一种新的开发方式ETS。本文通过ETS实现我们项目开发中常用的下拉选择菜单组件,来了解和体验ETS的开发规范和方法。主要用到的TS知识点有FlexLayout、文字展示、样式绑定、图片引入、父子组件变量共享、参数传递、ForEach循环遍历、事件绑定。用于实现效果的装饰器。装饰器装饰说明说明@Componentstruct结构装饰后具有基于组件的能力,需要实现build方法更新UI。@Entrystruct组件被装饰为页面的入口点,在页面加载时渲染显示。@Builder方法由@Builder装饰方法中的声明式UI描述,可以在自定义组件中快速生成多个布局内容。@Provide基本数据类型,类,数组@Provide作为数据提供者,可以更新其后代节点的数据,触发页面渲染。@Consume基本数据类型、类、数组@Consume装饰变量感知到@Provide装饰变量的更新后,会触发当前自定义组件的重新渲染。创建一个ETS项目在DevEcoStudio中新建一个ETS项目,语言选择ets。在entry->src->main->ets->default->pages目录下创建自己的.ets文件,就可以开始写ets代码了。功能分解为卡片创建了弹性布局。Flex({justifyContent:FlexAlign.SpaceBetween,alignItems:ItemAlign.Center}){}.height(64).width('100%').backgroundColor('#fff').borderRadius(16).padding({左:16,右:16})用内容填充卡片。Column(){Text('模式选择').fontSize(16)Text('清洁模式').fontSize(12).alignSelf(ItemAlign.Start).fontColor('rgba(0,0,0,0.6)').margin({top:2})}图片资源的引入,icon.png存在于resources->base->media目录下。Column(){Flex(){Image($r('app.media.icon')).objectFit(ImageFit.Contain)}.height(24).width(24)}绑定点击事件。.onClick(()=>{this.showSelector=!this.showSelector;console.log('showSelector==='+this.showSelector)})循环遍历标签。ForEach(this.modesData,item=>{Flex(){ModeItem({mode:item})}//为每个item绑定点击事件onClick(()=>{if(this.modeId!==item.id){this.modeId=item.idconsole.info('this.modeId==='+this.modeId)}this.showSelector=false})},item=>item.id.toString())父子组件共享变量。在父组件中使用@Provide修改变量,在子组件中使用@Consume修改同名变量,实现共享。//父组件@Entry@ComponentstructSelectorIndex{@ProvidemodeId:number=0//定义当前选中的itemidbuild(){Flex(){SelectorList()//显示子组件}}}//子组件@ComponentstructSelectorList{@ConsumemodeId:number//共享父组件属性build(){Flex(){}.onClick(()=>{console.log(this.modeId)//打印当前选中的itemid})}}Completecode//数据类型定义exportclassModeType{id:numbername:stringconstructor(id:number,name:string){this.id=id;this.name=名称;}}//单个选择的渲染@ComponentstructModeItem{privatemode:ModeType@ConsumemodeId:number@BuilderrenderModeItem(fontColor:string,bgColor:string,value:string){Flex({direction:FlexDirection.Column}){Flex(){Text(value).fontSize(16).fontColor(fontColor)}.height('100%').width('100%').backgroundColor(bgColor).borderRadius(12).padding({左:14,上:14,下:14})//最后一项不显示分隔符if(this.mode.id!=5){Flex(){Flex(){}.height(1).width('100%').backgroundColor('#F3F3F3')}.padding({left:12,right:12})}}}build(){Flex(){//选中项的样式与其他选项不同if(this.modeId==this.mode.id){this.renderModeItem('#0A59F7','#E6EEFF',this.mode.name)}else{this.renderModeItem('rgba(0,0,0,0.9)','',this.mode.name)}}.height(48)}}//下拉菜单组件@ComponentstructSelectorList{@ConsumemodesData:any//共享父组件属性@ConsumemodeId:number//共享父组件属性@ConsumeshowSelector:boolean//共享父组件属性build(){Flex({direction:FlexDirection.Column,justifyContent:FlexAlign.Start}){//循环生成下拉菜单ForEach(this.modesData,item=>{Flex(){ModeItem({mode:item})}//为每个item绑定点击事件onClick(()=>{if(this.modeId!==item.id){this.modeId=item.idconsole.info('this.modeId==='+this.modeId)}this.showSelector=false})},item=>item.id.toString())}.height(248).width('100%').backgroundColor('#fff').borderRadius(16).shadow({radius:50,color:'rgba(0,0,30,0.1500)'}).padding({left:4,right:4,top:4,bottom:4}).position({x:0,y:-260}).zIndex(1)}}//入口组件@Entry@ComponentstructSelectorIndex{@ProvideshowSelector:boolean=false//是否展开下拉菜单@ProvidemodesData:any=[{id:1,name:'节能模式'},{id:2,name:'强力模式'},{id:3,name:'deepmode'},{id:4,name:'cleanmode'},{id:5,name:'sensitivemode'}]@ProvidemodeId:number=0//当前选择itemidbuild(){Flex({direction:FlexDirection.Column,justifyContent:FlexAlign.Center,alignItems:ItemAlign.Center}){Flex({justifyContent:FlexAlign.Center,alignItems:ItemAlign.Center}){Text('other内容1')。fontSize(16)}.height(88).width('100%').backgroundColor('#fff').borderRadius(16)Flex({direction:FlexDirection.Column,alignItems:ItemAlign.Center}){if(this.showSelector){SelectorList()}Flex({justifyContent:FlexAlign.SpaceBetween,alignItems:ItemAlign.Center}){Column(){Text('模式选择').fontSize(16)if(this.getSelectedText()){Text(this.getSelectedText()).fontSize(12).alignSelf(ItemAlign.Start).fontColor('rgba(0,0,0,0.6)').margin({top:2})}}Column(){Flex(){Image($r('app.media.icon')).objectFit(ImageFit.Contain)}.height(24).width(24)}}.height(64).width('100%').backgroundColor('#fff').borderRadius(16).padding({left:16,right:16}).onClick(()=>{this.showSelector=!this.showSelector;console.log('showSelector==='+this.showSelector)})}.height(64).margin({top:12,bottom:12})Flex({justifyContent:FlexAlign.Center,alignItems:ItemAlign.Center}){Text('其他内容2').fontSize(16)}.height(88).width('100%').backgroundColor('#fff').borderRadius(16)}.height('100%').width('100%').backgroundColor('#f1f3f5').padding({left:12,right:12,top:16,bottom:16}).onClick(()=>{this.showSelector=false})}//获取选中项的内容getSelectedText(){constselectedItem=this.modesData.find(item=>{returnitem.id==this.modeId})if(selectedItem){returnselectedItem.name}return''}}总结从上面的例子我们可以感受到基于TS扩展的声明式开发范式的方舟开发框架,采用链式调试使用的编程方式可以更直观的描述UI界面。您不必关心框架如何实现UI绘制和渲染。此外,还提供丰富的系统能力接口,真正实现极简高效的开发。有兴趣的可以去看看官方的TS开发文档。详细的了解和学习。华为鸿蒙也正式发布了3款基于TS扩展的声明式开发范式的超级实用示例,分别是eTSBuildCommonView创建简单视图示例、eTSDefiningPageLayoutAndConnection页面布局与连接示例、eTSDrawingAndAnimation绘图与动画示例,大家可以下载代码体验学习。了解更多开源知识,请访问:开源基础软件社区https://ost.51cto.com。