版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
第6章构建应用程序UI—进阶针对不同的应用场景及技术背景,鸿蒙平台ArkUI框架提供了两种类型的UI开发范式:其一,基于ArkTS的声明式UI开发范式,简称“声明式开发范式”;其二,兼容JS的类Web的UI开发范式,简称“类Web开发范式”。由于声明式开发范式更接近自然语义的编程方式,开发方式高效简洁,因此,鸿蒙平台后续将主推声明式开发范式,所以,本章主要对声明式开发范式中的UI组件及其使用进行介绍。目录6.1常用布局组件6.2常用基础组件6.3弹窗6.4动画6.5事件及其处理6.6组件导航和页面路由6.7案例:多UIAbility和多页面跳转6.8练习:案例再现6.1常用布局组件为了设计美观的界面,需要将界面UI组件按一定的规则进行排列,为此,需要使用布局组件。ArkUI提供了许多布局组件,包括:线性布局、层叠布局、弹性布局、相对布局、栅格布局、创建列表、网格、瀑布流、轮播、选项卡等。下面对常用的布局组件及其使用进行介绍。6.1.1线性布局(Row/Column)线性布局包括两个组件:Row布局组件和Column布局组件,其中,Row布局组件按行方式排列组件,Column布局组件按列方式排列组件,关于Row和Column的详细介绍参见3.2节。6.1.2弹性布局(Flex)Flex弹性布局提供有效的方式对容器中的子元素进行排列、对齐和分配剩余空间。容器默认存在主轴与交叉轴,子元素默认沿主轴排列,如图。Flex弹性布局组件提供了多个用于控制布局行为的属性,这些常用属性名称及其功能如表。序号属性名称功能及其可选值1direction控制子元素的排列方向,也就是主轴方向。可选值及其功能:FlexDirection.Row,默认值,水平方向;FlexDirection.RowReverse,水平反方向;FlexDirection.Column:垂直方向;FlexDirection.ColumnReverse,垂直反方向。2wrapFlex可以是单行布局或者多行布局,默认情况下,Flex容器中的子元素是单行布局。wrap属性控制Flex是单行布局还是多行布局。可选值及其功能:FlexWrap.NoWrap,默认值,不换行;FlexWrap.Wrap,换行;FlexWrap.WrapReverse,反向换行;3justifyContent设置子元素在主轴方向的对齐方式,可选值及其功能:FlexAlign.Start,默认值,子元素在主轴方向起始端对齐;FlexAlign.Center,子元素在主轴方向居中对齐;FlexAlign.End,子元素在主轴方向终点端对齐;FlexAlign.SpaceBetween,Flex主轴方向均匀分配弹性元素,相邻子元素之间距离相同,第一个子元素和最后一个子元素与父元素边沿对齐;FlexAlign.SpaceAround,Flex主轴方向均匀分配弹性元素,相邻子元素之间距离相同,第一个子元素到主轴起始端的距离和最后一个子元素到主轴终点端的距离是相邻元素之间距离的一半;FlexAlign.SpaceEvenly,Flex主轴方向元素等间距布局,相邻子元素之间的间距、第一个子元素与主轴起始端的间距、最后一个子元素到主轴终点端的间距均相等。4alignItems设置子元素在交叉轴的对齐方式,可选值及其功能:ItemAlign.Auto,使用Flex容器中默认配置;ItemAlign.Start,交叉轴方向首部对齐;ItemAlign.Center,交叉轴方向居中对齐;ItemAlign.End,交叉轴方向底部对齐;ItemAlign.Stretch,交叉轴方向拉伸填充,在未设置尺寸时,拉伸到容器尺寸;ItemAlign.Baseline,交叉轴方向文本基线对齐;6.1.3层叠布局(Stack)Stack层叠布局组件对容器中的子元素组件层叠放置,也就是将子元素依次放入容器中,后面的子元素覆盖在前面的子元素上面。可以使用alignContent属性参数控制子元素位置的相对移动。下面举一个例子说明Stack布局的应用。这个例子结合Flex布局和Stack布局,设计一个应用APP的入口主界面,用于演示实现浮动按钮的效果。为此,在DevEco中新建一个名称为ch0601的工程,修改Index.ers为如下代码:@Entry@ComponentstructStackSample{privatearr:string[]=['APP1','APP2','APP3','APP4','APP5','APP6','APP7','APP8'];
build(){Stack({alignContent:Alignment.Bottom}){Flex({wrap:FlexWrap.Wrap}){ForEach(this.arr,(item:string)=>{Text(item).width(100).height(100).fontSize(16).margin(10).textAlign(TextAlign.Center).borderRadius(10).backgroundColor(0xFFFFFF)},(item:string):string=>item)}.width('100%').height('100%')
Flex({justifyContent:FlexAlign.SpaceEvenly,alignItems:ItemAlign.Center}){Text('联系人').fontSize(16)Text('设置').fontSize(16)Text('短信').fontSize(16)}.width('100%').height(50).backgroundColor('#16302e2e').margin({bottom:15}).borderRadius(15)}.width('100%').height('100%').backgroundColor('#CFD0CF')}}6.1.4列表(List)列表组件是一种复杂的容器组件,当列表项达到一定数量,内容超过屏幕大小时,可以自动提供滚动功能。它适合用于呈现大量同类型数据。在列表中显示数据集合是许多应用程序中的常见要求,例如通讯录、音乐列表、购物清单等。列表作为一种容器,会自动按其滚动方向排列子组件,向列表中添加组件或从列表中移除组件会重新排列子组件,例如,在垂直列表中,List按垂直方向自动排列作为列表子元素的ListItemGroup或ListItem。ListItemGroup用于列表数据的分组展示,其子组件也是ListItem。ListItem表示单个列表项,可以包含单个子组件。List组件默认滚动方向是垂直方向,即默认情况下不需要手动设置List方向,就可以构建一个垂直滚动列表。若是水平滚动列表场景,将List的listDirection属性设置为Axis.Horizontal即可实现。listDirection默认为Axis.Vertical,即默认是垂直方向。下面通过一个例子介绍List布局组件的使用。这个例子显示一组类似通讯录的信息,点击列表中的条目,将通过Toast显示通讯录名称。为此,新建名称为ch0602的鸿蒙工程,并且在resources/base/media资源目录下放置4张图片资源,然后修改Index.ets为如下代码:import{util}from'@kit.ArkTS';
classContact{key:string=util.generateRandomUUID(true);name:string;icon:Resource;phone:string;
constructor(name:string,icon:Resource,phone:string){=name;this.icon=icon;this.phone=phone;}}
@Entry@ComponentstructSimpleContacts{privatecontacts:Array<object>=[newContact('小明',$r("app.media.png001"),'140-0000-1234'),newContact('小红',$r("app.media.png002"),'140-0000-2234'),newContact('大卫',$r("app.media.png003"),'140-0000-3234'),newContact('大张',$r("app.media.png004"),'140-0000-4234'),];
build(){List({space:5}){ForEach(this.contacts,(item:Contact)=>{ListItem(){Row(){Image(item.icon).width(40).height(40).margin(10)Text().fontSize(20).width(70).textAlign(TextAlign.Center)Text(item.phone).fontSize(20)}.width('100%').justifyContent(FlexAlign.Start).onClick(()=>{this.getUIContext().getPromptAction().showToast({message:JSON.stringify(+':'+item.phone)});})}},(item:Contact)=>JSON.stringify(item))}.width('100%').divider({strokeWidth:1,color:Color.Brown,startMargin:10,endMargin:10})}}6.1.5网格(Grid/GridItem)网格布局是由“行”和“列”分割的单元格所组成。网格布局具有较强的页面均分能力,子组件占比控制能力,是一种重要自适应布局。通过设置行列数量与尺寸占比可以确定网格布局的整体排列方式。Grid组件提供了rowsTemplate和columnsTemplate属性用于设置网格布局行列数量与尺寸占比。它们是一个由多个空格和'数字+fr'间隔拼接的字符串,fr的个数即网格布局的行或列数,fr前面的数值大小,用于计算该行或列在网格布局宽度上的占比,最终决定该行或列宽度。。除了大小相同的等比例网格布局外,由不同大小的网格组成不均匀分布的网格布局场景在实际应用中十分常见。为了适应这种需求,在Grid组件中,可以在创建Grid时设置GridLayoutOptions属性实现单个网格横跨多行或多列的场景。下面举例说明Grid以及GridItem的使用。这个例子实现了一个不均匀占比的布局。为此,新建一个名称为ch0603的鸿蒙工程,修改Index.ets为如下代码:@Entry@ComponentstructIndex{privatelayoutOptions:GridLayoutOptions={regularSize:[1,1],onGetRectByIndex:(index:number)=>{if(index==0){//索引号0表示时0行0列的元素,以此类推return[0,0,1,1];//[rowStart,columnStart,rowSpan,columnSpan]}elseif(index==1){return[0,1,1,1];}elseif(index==2){return[0,2,1,2];}elseif(index==3){return[1,0,1,1];}elseif(index==4){return[1,1,1,2];}elseif(index==5){return[1,3,1,1];}else{return[0,0,0,0];}}}@StylestextGridItemStyles(){.backgroundColor(Color.Pink).foregroundColor(Color.Black).borderRadius(10).width('100%').height('100%')}
build(){Grid(undefined,this.layoutOptions){GridItem(){Text('会议').textGridItemStyles().textAlign(TextAlign.Center)}.margin(5)GridItem(){Text('签到').textGridItemStyles().textAlign(TextAlign.Center)}.margin(5)GridItem(){Text('签退').textGridItemStyles().textAlign(TextAlign.Center)}.margin(5)GridItem(){Text('举手').textGridItemStyles().textAlign(TextAlign.Center)}.margin(5)GridItem(){Text('投票').textGridItemStyles().textAlign(TextAlign.Center)}.margin(5)GridItem(){Text('打印').textGridItemStyles().textAlign(TextAlign.Center)}.margin(5)}.rowsTemplate('1fr1fr').columnsTemplate('1fr1fr1fr1fr').columnsGap(1).rowsGap(1).height('25%').width('100%')}}6.1.6轮播(Swiper)轮播Swiper组件提供滑动轮播显示的能力。Swiper是一个容器组件,当设置了多个子组件后,可以对这些子组件进行轮播显示。通常,在一些应用首页显示推荐的内容时,需要用到轮播显示的能力。可以通过Swiper的loop属性控制是否循环播放,该属性默认值为true;通过autoPlay属性,控制是否自动轮播子组件,该属性默认值为false;autoPlay为true时,会自动切换播放子组件,子组件与子组件之间的播放间隔通过interval属性设置,interval属性默认值为3000,单位毫秒;通过indicator属性,开发者可以设置导航点相对于Swiper组件上下左右四个方位的位置,同时也可以设置每个导航点的尺寸、颜色、蒙层和被选中导航点的颜色。下面举例说明Swiper组件的使用。这个例子在Swiper组件中显示一组图片,通过滑动切换显示的图片。为此,新建名称为ch0604的鸿蒙工程,在ets目录下新建images子目录,在images子目录下放置要显示的图片。修改Index.ets为如下代码:@Entry@ComponentstructIndex{build(){Swiper(){Image('images/a01.jpg').width('100%').height(250).margin(2).backgroundColor(Color.Gray)
Image('images/a02.jpg').width('100%').height(250).margin(2).backgroundColor(Color.Gray)
Image('images/a03.jpg').width('100%').height(250).margin(2).backgroundColor(Color.Gray)
Image('images/a04.jpg').width('100%').height(250).margin(2).backgroundColor(Color.Gray)}.loop(true)}}运行这个程序.6.1.7选项卡(Tabs)当页面信息较多时,可以采用Tabs组件对页面内容进行分类,提高页面空间利用率。Tabs组件可以在一个页面内快速实现视图内容的切换,一方面提升查找信息的效率,另一方面精简用户单次获取到的信息量。Tabs组件的页面组成包含两个部分,分别是TabContent和TabBar:TabContent是内容页,TabBar是导航页签栏。根据不同的导航类型,Tabs的页面结构可以分为底部导航、顶部导航、侧边导航,其导航栏分别位于底部、顶部和侧边,如图6-9所示,使用Tabs的barPosition参数设置导航栏位置,默认情况下,导航栏位于顶部,此时,barPosition的值为BarPosition.Start;设置为底部导航时,将barPosition设置为BarPosition.End即可。实现侧边导航栏需要将Tabs的vertical属性设置为true,vertical默认值为false。导航栏的页签超过屏幕宽度时,可以设置Tabs组件的barMode属性使导航栏滚动,默认值为BarMode.Fixed表示为固定导航栏,BarMode.Scrollable表示可滚动导航栏。Tabs使用花括号包裹TabContent,TabContent显示相应的内容页,并且通过TabContent的tabBar属性配置页签。下面举个例子说明Tabs组件的使用。这个例子使用标签页显示不同的信息,包括:图片,文字等。为此,新建名称为ch0605的鸿蒙工程,在ets目录下新建images子目录,并在其中放置一些图片,然后修改Index.ets为如下内容:@Entry@ComponentstructIndex{build(){Tabs({barPosition:BarPosition.Start}){TabContent(){Text('Loremipsumdolorsitamet,consecteturadipiscingelit.'+'Naminscelerisquesem.Maurisvolutpat,doloridinterdumullamcorper,'+'risusdoloregestaslectus,sitametmattispurusduinecrisus.'+'Maecenasnonsodalesnisi,veldictumdolor.Classaptenttacitisociosqu'+'adlitoratorquentperconubianostra,perinceptoshimenaeos.Suspendisse'+'blanditeleifenddiam,velrutrumtellusvulputatequis.Aliquameget'+'liberoaliquet,imperdietnisla,ornareex.Sedrhoncusestutlibero'+'portalobortis.Fusceindictumtellus.').fontSize(20)}.tabBar('首页').align(Alignment.TopStart)
TabContent(){Image('images/a03.jpg').height(250).width('100%')}.tabBar('美图')
TabContent(){Text('发现的内容').fontSize(30)}.tabBar('发现')
TabContent(){Text('我的内容').fontSize(30)}.tabBar("我的")}.height('100%').width('100%')}}运行这个程序。6.2常用基础组件在页面设计除了上一节介绍的常用布局组件外,还有许多常用的基础组件,例如,用于文本信息的Text文本组件、Button按钮组件、Image图像组件、视屏播放Video组件等。本节对常用的组件进行介绍。6.2.1Text、Button、Image以及InputText组件关于Text组件、Button组件、Image组件以及InputText组件的使用,已经在3.2节做了介绍,这里不再赘述。6.2.2单选框(Radio)Radio是单选框组件,通常用于提供相应的用户交互选择项,在创建Radio组件时,可以指定Radio组件所属组,同一组的Radio中只有一个可以被选中。创建Radio组件时,可以传递一个RadioOptions参数,通过这个参数,配置Radio组件的显示值以及所属组:value是单选框的名称;group是单选框的所属群组名称;checked属性可以设置单选框的状态。除支持通用事件外,Radio还用于选中后触发某些操作,可以绑定onChange事件来响应选中操作后的自定义行为。关于Radio的应用举例将在下一节给出。6.2.3切换按钮(Toggle)Toggle组件就是常见的复选框,它提供状态按钮样式、勾选框样式和开关样式,一般用于两种状态之间的切换。通过传递给Toggle组件一个ToggleOptions对象参数来指定Toggle组件的样式以及选中状态:ToggleType为开关类型,可取值包括Button、Checkbox和Switch样式;isOn为切换按钮的状态。当ToggleType为Checkbox或者Switch时,用于创建不包含子组件的Toggle;当ToggleType为Button时,只能包含一个子组件,如果子组件有文本设置,则相应的文本内容会显示在按钮上。与Radio类似,Toggle组件除支持通用事件外,还可以在选中和取消选中后触发某些操作,可以绑定onChange事件来响应操作后的自定义行为。下面举个例子说明Radio组件以及Toggle组件的使用。分别使用Toggle和Radio表示蓝牙的开启状态和方位设置。为此,新建名称为ch0606的鸿蒙工程,修改Index.ets为如下代码:import{promptAction}from'@kit.ArkUI';
@Entry@ComponentstructToggleExample{@StateBOnSt:promptAction.ShowToastOptions={'message':'Bluetoothison.'};@StateBOffSt:promptAction.ShowToastOptions={'message':'Bluetoothisoff.'};
build(){Column(){Row(){Text("BluetoothMode").height(50).fontSize(16)}Row(){Text("Bluetooth").height(50).padding({left:10}).fontSize(16).textAlign(TextAlign.Start).backgroundColor(0xFFFFFF)Toggle({type:ToggleType.Switch}).margin({left:200,right:10}).onChange((isOn:boolean)=>{if(isOn){this.getUIContext().getPromptAction().showToast(this.BOnSt);}else{this.getUIContext().getPromptAction().showToast(this.BOffSt);}})}.backgroundColor(0xFFFFFF).width('100%')
Row(){Text("方位").height(50).fontSize(16)}Grid(){GridItem(){Text('东')}GridItem(){Text('南')}GridItem(){Text('西')}GridItem(){Text('北')}GridItem(){Radio({value:'1',group:'dir'}).checked(true)}GridItem(){Radio({value:'2',group:'dir'})}GridItem(){Radio({value:'3',group:'dir'})}GridItem(){Radio({value:'4',group:'dir'})}}.backgroundColor(0xFFFFFF).width('100%').height(60).rowsTemplate('1fr1fr').columnsTemplate('1fr1fr1fr1fr')}.padding(10).backgroundColor(0xDCDCDC).width('100%').height('100%')}}运行这个程序。6.2.4进度条(Progress)Progress是进度条显示组件,显示内容通常为目标操作的当前进度。可以通过传递一个ProgressOptions对象来创建Progress进度条组件:ProgressOptions对象的value用于设置初始进度值,total用于设置进度总长度,type用于设置Progress样式。Progress进度有5种可选样式,通过ProgressType进行设置:ProgressType.Linear,线性样式;ProgressType.Ring,环形无刻度样式;ProgressType.ScaleRing,环形有刻度样式;ProgressType.Eclipse,圆形样式和ProgressType.Capsule,胶囊样式。看一个简单的进度条应用示例。这个例子显示一个进度条,点击按钮,可以更新进度条的进度值。为此,新建名称ch0607的鸿蒙程序工程,修改Index.ets为如下代码:@Entry@ComponentstructProgressCase1{@StateprogressValue:number=0;//设置进度条初始值为0build(){Column(){Column(){Progress({value:0,total:100,type:ProgressType.Capsule}).width('100%').height(50).value(gressValue).margin({top:20})Row().width('100%').height(5)Button("进度条+5").width('100%').margin(10).onClick(()=>{gressValue+=5;if(gressValue>100){gressValue=0;}})}}.width('100%').height('100%')}}运行这个程序。6.2.5视频播放(Video)Video组件用于播放视频文件并控制其播放状态,常用于为短视频和应用内部视频的列表页面。当视频完整出现时会自动播放,用户点击视频区域则会暂停播放,同时显示播放进度条,通过拖动播放进度条指定视频播放到具体位置。Video组件可以播放本地视频以及网络视频,通过传递一个VideoOptions对象参数即可创建Video组件。下面举一个例子说明Video组件的使用。这个例子播放放置在程序资源rawfile资源目录下的本地视频。为此,新建一个名称为ch0608的鸿蒙程序工程,在resources目录下的rawfile子目录下放置一个视频文件,然后,修改Index.ers为如下内容:@ComponentstructVideoPlayer{privatecontroller:VideoController=newVideoController()privatepreviewUris:Resource=$r('app.media.preview')privateinnerResource:Resource=$rawfile('samplev.mp4')
build(){Column(){Video({src:this.innerResource,//设置视频源previewUri:this.previewUris,//设置预览图controller:this.controller//设置视频控制器,可以控制视频的播放状态}).controls(true)//设置是否显示默认控制条.autoPlay(true)//设置是否自动播放.width('100%').height(300)}}}
@Entry@ComponentstructIndex{@Statemessage:string='播放视频';
build(){Column(){Text(this.message).fontSize(30).fontWeight(FontWeight.Bold).margin(20).onClick(()=>{})VideoPlayer()}.height('100%').width('100%')}}运行这个程序。6.2.6图标小符号(SymbolGlyph/SymbolSpan)SymbolGlyph是图标小符号组件,便于使用精美的图标,如渲染多色图标和使用动效图标;SymbolSpan作为Text组件的子组件,可在文本中穿插显示图标小符号。SymbolGlyph通过$r引用Resource资源来创建,目前仅支持系统预置的Symbol资源名。SymbolSpan可作为Text的子组件用于显示图标小符号,可以在一个Text组件内添加多个SymbolSpan,从而展示一串连续的图标。下面举一个例子说明SymbolGlyph组件和SymbolSpan组件的使用。这个例子分别使用SymbolGlyph组件和SymbolSpan组件显示一组鸿蒙系统的资源图标。为此,新建名称为ch0609的鸿蒙工程,修改Index.ets为如下代码:@Entry@ComponentstructIndex{privateglyphs:Resource[]=[$r('sys.symbol.card_migration'),$r('sys.symbol.car_side_rear'),$r('sys.symbol.camera_master_ai'),$r('sys.symbol.bicycle'),$r('sys.symbol.cake'),$r('sys.symbol.ohos_wifi'),];privatetexts:string[]=['卡片','汽车','相机','自行车','蛋糕','WIFI'];
build(){Column(){Grid(){ForEach(this.glyphs,(item:Resource,index:number)=>{GridItem(){SymbolGlyph(item).fontSize(96).renderingStrategy(SymbolRenderingStrategy.SINGLE).fontColor([Color.Black,Color.Green,Color.White])}.onClick(()=>{this.getUIContext().getPromptAction().showToast({'message':index.toString()});})},(item:Resource,index:number)=>index.toString())}.rowsTemplate('1fr1fr').columnsTemplate('1fr1fr1fr').height('30%').width('100%')
Grid(){ForEach(this.glyphs,(item:Resource,index:number)=>{GridItem(){Column(){Text(){SymbolSpan(item).fontSize(48).renderingStrategy(SymbolRenderingStrategy.SINGLE).fontColor([Color.Black,Color.Green,Color.White])}Text(this.texts[index])}}.onClick(()=>{this.getUIContext().getPromptAction().showToast({'message':index.toString()});})},(item:Resource,index:number)=>index.toString())}.rowsTemplate('1fr1fr').columnsTemplate('1fr1fr1fr').height('30%').width('100%').margin({top:50})}.width('100%').height('100%')}}运行这个程序。6.3弹窗弹窗应用运行过程中根据需要弹出或者根据用户行为操作时弹出的UI界面,用于短时间内展示用户需关注的信息或待处理的操作。根据用户交互操作场景,弹窗可分为模态弹窗和非模态弹窗两种类型,其区别在于用户是否必须对其做出响应,其中,模态弹窗:强交互形式,会中断用户当前的操作流程,要求用户必须做出响应才能继续其他操作,通常用于需要向用户传达重要信息的场景;非模态弹窗:弱交互形式,不会影响用户当前操作行为,用户可以不对其进行回应,通常都有时间限制,出现一段时间后会自动消失,一般用于告诉用户信息内容外还需要用户进行功能操作的场景。本节对常用的弹窗,包括:弹出框(Dialog)、气泡提示(Popup/openPopup)、即时反馈(Toast)的使用进行介绍。6.3.1弹出框(Dialog)弹出框是一种常见的窗口,通常用于在保持当前上下文环境的同时,向用户需展示需要关注的信息或待需要处理的操作。鸿蒙提供了一组常用的弹出窗,包括:对话框(showDialog)、警告弹窗(AlertDialog)、选择器弹窗(PickerDialog)、列表选择弹窗(ActionSheet)、操作菜单(showActionMenu)等。这些弹出框的使用方式都非常类似:通过调用UIContext对象的getXXX()方法获取到相关弹出框对象,再通过该对象调用showXXX()接口方法弹出相关窗口。下面举例子说明如何使用这些弹出框。这个例子首先在Grid组件中显示一组按钮,点击相应按钮将显示不同的弹出框。为此,新建名称为ch0610的鸿蒙工程,修改Index.ets为如下代码:@Entry@ComponentstructIndex{@StateselectTime:Date=newDate('2024-01-01T08:30:00');
build(){Grid(){GridItem(){Column(){SymbolGlyph($r('sys.symbol.v_diamond')).fontSize(96)Text('对话框').margin(10)}.onClick(()=>{try{this.getUIContext().getPromptAction().showDialog({title:'这是对话框',message:'对话框的信息可以在这里显示',buttons:[{text:'确定',color:'#000000'},{text:'取消',color:'#000000'}]},(err,data)=>{if(err){console.error('showDialogerr:'+err);return;}this.getUIContext().getPromptAction().showToast({'message':'点击了编号为:'+data.index+'的按钮'});});}catch(error){}})}GridItem(){Column(){SymbolGlyph($r('sys.symbol.card_badge_shield')).fontSize(96)Text('警告框').margin(10)}.onClick(()=>{this.getUIContext().showAlertDialog({title:'这是警告框',message:'警告框的文字可以显示在这里',autoCancel:true,alignment:DialogAlignment.Center,offset:{dx:0,dy:-20},buttons:[{value:'cancel',action:()=>{('Callbackwhenthefirstbuttonisclicked');}},{value:'ok',enabled:true,defaultFocus:true,style:DialogButtonStyle.HIGHLIGHT,action:()=>{('Callbackwhenthesecondbuttonisclicked');}}],});})}
GridItem(){Column(){SymbolGlyph($r('sys.symbol.capture_smiles')).fontSize(96)Text('选择日期').margin(10)}.onClick(()=>{this.getUIContext().showDatePickerDialog({start:newDate("2000-1-1"),end:newDate("2100-12-31"),selected:this.selectTime,lunarSwitch:true,showTime:true,onDateAccept:(value:Date)=>{this.selectTime=value;this.getUIContext().getPromptAction().showToast({'message':JSON.stringify(value)});},});})}}.rowsTemplate('1fr').columnsTemplate('1fr1fr1fr').height('30%').width('100%')}}运行这个程序。6.3.2气泡提示(Popup)气泡提示是一种给用户提供提示的弹窗,例如点击一个问号图标弹出一段帮助提示等。气泡分为两种类型,一种是系统提供的气泡PopupOptions,一种是开发者可以自定义的气泡CustomPopupOptions,本节主要介绍系统提供的PopupOptions气泡。组件通过设置bindPopup属性参数来控制是否弹出气泡,bindPopup属性的第一个参数为boolean类型,用于控制是否显示气泡;第二个参数是一个PopupOptions对象,用于控制气泡的外观及行为。下面举一个简单的例子看看Popup的应用。在这个例子中,在主界面上显示一个按钮,当用户点击这个按钮时将显示一个气泡,在气泡中又有两个按钮,当用户点击气泡上的“确认”按钮时气泡将消失。为此,新建一个名称为ch0611的鸿蒙工程,修改Index.ets如下代码:@Entry@ComponentstructPopupExample22{@Stateshow:boolean=false;
build(){Column(){Button('弹出气泡').margin({top:50}).onClick(()=>{this.show=!this.show;}).bindPopup(this.show,{message:'ThisisapopupwithPopupOptions',primaryButton:{value:'确定',action:()=>{this.show=!this.show;}},secondaryButton:{value:'取消',action:()=>{//this.show=!this.show;}},onStateChange:(e)=>{if(!e.isVisible){this.show=false;}},})}.width('100%').padding({top:5})}}运行这个程序。6.3.3即时反馈(Toast)即时反馈(Toast)是一种临时性的消息提示框,用于向用户显示简短的操作反馈或状态信息。它通常在屏幕的底部或顶部短暂弹出,随后在一段时间后自动消失。即时反馈的主要目的是提供简洁、不打扰的信息反馈,避免干扰用户当前的操作流程。可以通过使用UIContext中的getPromptAction方法获取当前UI上下文关联的PromptAction对象,再通过该对象调用showToast创建并显示文本提示框。之前的例子中已经由多个关于Toast的使用举例,例如6.4.2节,此处不再赘述。在此总结一下Toast的使用。组件程序中,使用类似如下代码显示一个Toast组件:this.getUIContext().getPromptAction().showToast({'message':‘要显示的消息’});6.4动画动画是一种常见的界面视觉增强技术。通过动画,应用程序可以为UI的变化添加过渡场景,如开机、应用程序启动或退出、下拉进入控制中心等,从而增加程序的视觉效果。ArkUI提供多种动画接口,包括组件动画、属性动画、转场动画等。下面分别对这些常用动画进行介绍。6.4.1组件动画ArkUI为部分基础组件及布局组件提供了默认的动画效果,例如,List的滑动动效、Button的点击动效等,这些默认的动画形式称为组件动画。开发者在开发过程中可以直接使用这些组件动画,而无需做任何辅助工作。6.4.2属性动画属性动画是最基础的动画类型,这种动画形式会根据组件的某些可动画属性,例如,尺寸属性、布局属性、位置属性等,逐帧驱动属性的变化,产生一帧帧的动画效果,并且动画过程的驱动由系统自动完成,应用APP不参与动画过程。常用的组件可动画属性包括:位置、大小、内边距、外边距、对齐方式、背景颜色、背景模糊、文字大小、文字颜色,图片对齐方式、前景颜色、透明度、圆角、边框、阴影等。下面举一个例子说明如何使用组件的属性动画。这个例子通过在程序中改变按钮组件的位置、旋转角度和透明度属性值从而产生动画效果。为此,新建名称为ch0612的鸿蒙工程,修改Index.ets为如下代码:import{curves}from'@kit.ArkUI';
@Entry@ComponentstructAnimationDemo{@Statenow:boolean=false;//声明相关状态变量,这些状态变量作为属性值将控制组件的外观@StaterotateValue:number=0;@StatetranslateX:number=0;@StateopacityValue:number=1;
//将状态变量设置到组件的可动画属性build(){Row(){//组件一Column(){}.opacity(this.opacityValue).rotate({angle:this.rotateValue})//这里很重要:通过属性动画接口开启属性动画.animation({curve:curves.springMotion()}).backgroundColor('#317AF7').justifyContent(FlexAlign.Center).width(100).height(100).borderRadius(30).onClick(()=>{this.now=!this.now;//改变状态变量的值,从而改变UI界面外观this.rotateValue=this.now?90:0;this.translateX=this.now?50:0;this.opacityValue=this.now?0.6:1;})
//组件二Column(){}.justifyContent(FlexAlign.Center).width(100).height(100).backgroundColor('#D94838').borderRadius(30).opacity(this.opacityValue).translate({x:this.translateX}).animation({curve:curves.springMotion()})}.width('100%').height('20%').justifyContent(FlexAlign.Center)}}运行这个程序。6.4.3转场动画转场动画则为组件在出现和消失时添加过渡动画,目的在于增强界面专场的视觉效果。转场动画分为基础转场和高级模板化转场,常用的转场动画有如下几类:其一,出现/消失转场;其二,模态转场;其三,导航转场。下面对出现/消失转场和模态转场进行介绍,关于导航转场,在页面导航一节介绍。1、出现/消失转场组件的出现/消失转场效果,可以通过组件的transition属性接口结合TransitionEffect对象参数来定义,这两者的结合可以定义出各种转场动画效果。TransitionEffect对象包括如下表所示的常用转场动画效果。序号转场效果说明1IDENTITY禁用转场效果2OPACITY默认的转场效果,透明度转场3SLIDE滑动转场效果,出现时从窗口左侧滑入,消失时从窗口右侧滑出4translate通过设置组件平移创建转场效果5rotate通过设置组件旋转创建转场效果6opacity通过设置透明度参数创建转场效果7move通过TransitionEdge创建从窗口哪条边缘出来的效果8asymmetric通过此方法组合非对称的出现消失转场效果:appear,出现转场的效果;disappear,消失转场的效果。9combine组合其他TransitionEffect10animation定义转场效果的动画参数下面看一个具体的例子来体会表6-2的各个转场动画的效果。这个例子将一个文本框组件通过转场方式旋转及移动到它本来应该出现的位置。为此,新建名称ch0613的鸿蒙工程,修改Index.ets为如下代码:@Entry@ComponentstructTransitionEffectDemo{@StateisPresent:boolean=false;privateeffect:TransitionEffect=TransitionEffect.OPACITY.animation({curve:curves.springMotion()}).combine(TransitionEffect.scale({x:0,y:0})).combine(TransitionEffect.rotate({angle:90})).combine(TransitionEffect.move(TransitionEdge.TOP)).animation({duration:2000,curve:Curve.Friction,delay:100});
build(){Stack(){if(this.isPresent){Column(){Text('ArkUI').fontWeight(FontWeight.Bold).fontSize(20).fontColor(Color.White)}.justifyContent(FlexAlign.Center).backgroundColor(0xf56c6c).width(150).height(150).borderRadius(10).transition(this.effect)}
Button('Click').margin({top:300}).onClick(()=>{this.isPresent=!this.isPresent;})}.width('100%').height('60%')}}运行这个程序。2、模态转场模态转场是新的界面覆盖在旧的界面上,旧的界面不消失的一种转场方式。鸿蒙系统支持如下方式的模态转场:使用bindContentCover构建全屏模态转场、使用bindSheet构建半模态转场、使用bindMenu实现菜单弹出、使用bindContextMenu实现菜单弹出、使用bindPopUp实现气泡弹窗、使用if实现模态转场。这些转场方式的使用比较类似,限于篇幅,本节只对使用bindContentCover构建全屏模态转场进行介绍。bindContentCover接口用于为组件绑定全屏模态页面,在组件出现和消失时可通过设置转场参数ModalTransition添加过渡动效。看一个简单例子。这个例子模拟一个购票APP,当用户点击购票人按钮时,将弹出一个购票人选择列表共用户选择。为此,新建一个名称为ch0614的鸿蒙工程,修改Index.ets为如下代码:import{curves}from'@kit.ArkUI';
interfacePerson{name:string,cardnum:string}
@Entry@ComponentstructBindContentCoverDemo{privatepersonList:Array<Person>=[{name:'王**',cardnum:'1234***********789'},{name:'宋*',cardnum:'2345***********789'},{name:'许**',cardnum:'3456***********789'},{name:'唐*',cardnum:'4567***********789'}];@StateisPresent:boolean=false;
@BuilderMyBuilder(){Column(){Row(){Text('选择乘车人').fontSize(20).fontColor(Color.White).width('100%').textAlign(TextAlign.Center).padding({top:30,bottom:15})}.backgroundColor(0x007dfe)
Row(){Text('+添加乘车人').fontSize(16).fontColor(0x333333).margin({top:10}).padding({top:20,bottom:20}).width('92%').borderRadius(10).textAlign(TextAlign.Center).backgroundColor(Color.White)}
Column(){ForEach(this.personList,(item:Person,index:number)=>{Row(
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 九江中考历史试卷答案
- 北森测评题库98题答案
- 2026年曲靖银行业专业人员中级职业资格考试(专业实务个人理财)试题及答案
- 2026年湖南省耒阳市高一数学上册期末考试模拟检测卷及参考答案【模拟题】
- 执业医师试题库带答案
- 军考科技知识题库及答案
- 工程造价专科题库答案
- 2026年国企中层干部竞聘笔试题目及答案
- 2026年浙江省奉化市高一数学上册期末考试模拟测试卷附答案(基础题)
- 2026年山东省招远市高一数学上册期末考试模拟考试卷及参考答案【基础题】
- 2025福建中闽海上风电有限公司招聘5人笔试参考题库附带答案详解
- 《一年级期末总结班会》 课件
- T∕JSF 041-2025 抗松墨天牛马尾松鉴定技术规程
- 铝型材开模合同范本
- 二十四节气课件
- 心源性心脏病课件
- 脚手架施工安全风险评估方案
- 2025年新媒体运营师(中级)考试真题试卷及详细答案
- GB/T 20065-2025预应力混凝土用螺纹钢筋
- 旅游景区安全与消防培训课件
- 盐酸利托君的应用及护理
评论
0/150
提交评论