一、需求分析
相信大家都接过电话吧,咳咳,本节来模拟一个不喜欢接电话的小朋友,在切换界面上加上小红点,具体的通话界面之后可能会做
实现页面切换
不同页面显示不同内容
可显示角标(小红点)
二、控件介绍
(1)Tabs
一种可以通过页签进行内容视图切换的容器组件,每个页签对应一个内容视图。
说明:
该组件从API Version 7开始支持。后续版本如有新增内容,则采用上角标单独标记该内容的起始版本。
接口
Tabs(value?: {barPosition?: BarPosition, index?: number, controller?: TabsController})
参数:
参数名 | 参数类型 | 必填 | 参数描述 |
---|---|---|---|
barPosition | BarPosition | 否 | 指定页签位置来创建Tabs容器组件。 默认值:BarPosition.Start |
index | number | 否 | 指定初次初始页签索引。 默认值:0 |
controller | TabsController | 否 | 设置Tabs控制器。 |
BarPosition枚举说明
名称 | 描述 |
---|---|
Start | vertical属性方法设置为true时,页签位于容器左侧;vertical属性方法设置为false时,页签位于容器顶部。 |
End | vertical属性方法设置为true时,页签位于容器右侧;vertical属性方法设置为false时,页签位于容器底部。 |
属性
不支持触摸热区设置,除支持通用属性外,还支持以下属性:
名称 | 参数类型 | 描述 |
---|---|---|
vertical | boolean | 设置为false是为横向Tabs,设置为true时为纵向Tabs。 默认值:false |
scrollable | boolean | 设置为true时可以通过滑动页面进行页面切换,为false时不可滑动切换页面。 默认值:true |
barMode | BarMode | TabBar布局模式,具体描述见BarMode枚举说明。 默认值:BarMode.Fixed |
barWidth | number | Length8+ | TabBar的宽度值。 |
barHeight | number | Length8+ | TabBar的高度值。 |
animationDuration | number | TabContent滑动动画时长。 默认值:200 |
BarMode枚举说明
名称 | 描述 |
---|---|
Scrollable | TabBar使用实际布局宽度, 超过总长度后可滑动。 |
Fixed | 所有TabBar平均分配宽度。 |
(2)TabContentOpenAtom OpenHarmony
仅在Tabs中使用,对应一个切换页签的内容视图。
说明:
该组件从API Version 7开始支持。后续版本如有新增内容,则采用上角标单独标记该内容的起始版本。
属性
除支持通用属性外,还支持以下属性:
名称 | 参数类型 | 描述 |
---|---|---|
tabBar | string | Resource | { icon?: string | Resource, text?: string | Resource } | CustomBuilder8+ | 设置TabBar上显示内容。 CustomBuilder: 构造器,内部可以传入组件(API8版本以上适用)。 > 说明: > 如果icon采用svg格式图源,则要求svg图源删除其自有宽高属性值。如采用带有自有宽高属性的svg图源,icon大小则是svg本身内置的宽高属性值大小。 |
说明:
TabContent组件不支持设置通用宽度属性,其宽度默认撑满Tabs父组件。
TabContent组件不支持设置通用高度属性,其高度由Tabs父组件高度与TabBar组件高度决定。
TabContent组件不支持触摸热区设置。
// xxx.ets @Entry @Component struct TabContentExample { @State fontColor: string = 'rgba(0, 0, 0, 0.4)' @State selectedFontColor: string = 'rgba(10, 30, 255, 1)' @State currentIndex: number = 0 private controller: TabsController = new TabsController() @Builder TabBuilder(index: number) { Column() { Image(this.currentIndex === index ? '/resources/ic_public_contacts_filled_selected.png' : '/resources/ic_public_contacts_filled.png') .width(10) .height(10) .opacity(this.currentIndex === index ? 1 : 0.4) .objectFit(ImageFit.Contain) Text(`Tab${(index > 2 ? (index - 1) : index) + 1}`) .fontColor(this.currentIndex === index ? this.selectedFontColor : this.fontColor) .fontSize(10) .margin({top: 2}) } } @Builder AddBuilder() { Column() { Image(this.currentIndex === 2 ? '/resources/ic_public_add_norm_filled_selected.png' : '/resources/ic_public_add_norm_filled.png') .width(this.currentIndex === 2 ? 26 : 24) .height(this.currentIndex === 2 ? 26 : 24) .opacity(this.currentIndex === 2 ? 1 : 0.4) .objectFit(ImageFit.Contain) .animation({duration: 200}) } } build() { Column() { Tabs({ barPosition: BarPosition.End, controller: this.controller }) { TabContent() { Flex({justifyContent: FlexAlign.Center}) { Text('Tab1').fontSize(32) } }.tabBar(this.TabBuilder(0)) TabContent() { Flex({justifyContent: FlexAlign.Center}) { Text('Tab2').fontSize(32) } }.tabBar(this.TabBuilder(1)) TabContent() { Flex({justifyContent: FlexAlign.Center}) { Text('Add').fontSize(32) } }.tabBar(this.AddBuilder()) TabContent() { Flex({justifyContent: FlexAlign.Center}) { Text('Tab3').fontSize(32) } }.tabBar(this.TabBuilder(3)) TabContent() { Flex({justifyContent: FlexAlign.Center}) { Text('Tab4').fontSize(32) } }.tabBar(this.TabBuilder(4)) } .vertical(false) .barWidth(300).barHeight(56) .onChange((index: number) => { this.currentIndex = index }) .width('90%').backgroundColor('rgba(241, 243, 245, 0.95)') }.width('100%').height(200).margin({ top: 5 }) } }
(3)BadgeOpenAtom OpenHarmony
可以附加在单个组件上用于信息标记的容器组件。
说明: 该组件从API Version 7开始支持。后续版本如有新增内容,则采用上角标单独标记该内容的起始版本。
Badge({ value: ' ', position: BadgePosition.Left, // 设置 badge 居左显示 style: {badgeSize: 10, badgeColor: Color.Red}// 设置 badge 的显示样式 }) { Text("Badge") .size({width: 100, height: 50}) .fontSize(20) .backgroundColor("#aabbcc") } .size({width: 100, height: 50}) Badge({ value: ' ', position: BadgePosition.Right, // 设置 badge 居右显示 style: {badgeSize: 10, badgeColor: Color.Red}// 设置 badge 的显示样式 }) { Text("Badge") .size({width: 100, height: 50}) .fontSize(20) .backgroundColor("#aabbcc") } .size({width: 100, height: 50}) Badge({ value: ' ', position: BadgePosition.RightTop, // 设置 badge 居右上角显示 style: {badgeSize: 10, badgeColor: Color.Red}// 设置 badge 的显示样式 }) { Text("Badge") .size({width: 100, height: 50}) .fontSize(20) .backgroundColor("#aabbcc") } .size({width: 100, height: 50})
三、UI设计
(1)页面切换
首先需要创建一个TabContent组件,实现页面切换
@Entry @Component struct TabsTest { private controller: TabsController = new TabsController(); @State index: number = 0; // 选项卡下标,默认为第一个 @Builder tabMessage() { // 自定义消息标签 Column() { Column() { Blank() Image(this.index == 0 ? 'pages/icon_message_selected.png' : 'pages/icon_message_normal.png') .size({width: 25, height: 25}) Text('消息') .fontSize(16) .fontColor(this.index == 0 ? "#2a58d0" : "#6b6b6b") Blank() } .height('100%') .width("100%") .onClick(() => { this.index = 0; this.controller.changeIndex(this.index); }) } } @Builder tabContract() { // 自定义联系人标签 Column() { Blank() Image(this.index == 1 ? 'pages/icon_contract_selected.png' : 'pages/icon_contract_normal.png') .size({width: 25, height: 25}) Text('联系人') .fontSize(16) .fontColor(this.index == 1 ? "#2a58d0" : "#6b6b6b") Blank() } .height('100%') .width("100%") .onClick(() => { this.index = 1; this.controller.changeIndex(this.index); }) } @Builder tabDynamic() { // 自定义动态标签 Column() { Blank() Image(this.index == 2 ? 'pages/icon_dynamic_selected.png' : 'pages/icon_dynamic_normal.png') .size({width: 25, height: 25}) Text('动态') .fontSize(16) .fontColor(this.index == 2 ? "#2a58d0" : "#6b6b6b") Blank() } .height('100%') .width("100%") .onClick(() => { this.index = 2; this.controller.changeIndex(this.index); }) } build() { Column() { Tabs({ barPosition: BarPosition.End, // TabBar排列在下方 controller: this.controller // 绑定控制器 }) { TabContent() { Column() { Text('消息') .fontSize(30) } .width('100%') .height('100%') .backgroundColor("#aabbcc") } .tabBar(this.tabMessage) // 使用自定义TabBar TabContent() { Column() { Text('联系人') .fontSize(30) } .width('100%') .height('100%') .backgroundColor("#bbccaa") } .tabBar(this.tabContract) // 使用自定义TabBar TabContent() { Column() { Text('动态') .fontSize(30) } .width('100%') .height('100%') .backgroundColor("#ccaabb") } .tabBar(this.tabDynamic) // 使用自定义TabBar } .width('100%') .height('100%') .barHeight(60) .barMode(BarMode.Fixed) // TabBar均分 .onChange((index: number) => { // 页面切换回调 this.index = index; }) } .width('100%') .height('100%') } }
(2)图标修改
在Tab组件中,图标需要选择两种风格,一个是没有点击到的,另一个是被选中的状态,我这里使用本色和红色来演示
(3)角标添加
这里加入传统的角标颜色,小红点来实现,当前未接电话有14个
@Builder tabMessage() { // 自定义消息标签 Badge({ count: 14, // 设置 badge 显示的数量 maxCount: 100, // 设置 badge 显示的最大数量 position: BadgePosition.RightTop,// 设置 badge 显示在右上角 style: {badgeColor: Color.Red,fontSize:15,badgeSize:30} // 设置 badge 的显示样式 }) { Column() { Column() { Blank() Image(this.index == 0 ? 'pages/电话2.png' : 'pages/电话.png') .size({ width: 25, height: 25 }) Text('电话') .fontSize(16) .fontColor(this.index == 0 ? "#2a58d0" : "#6b6b6b") Blank() } .height('100%') .width("100%") .onClick(() => { this.index = 0; this.controller.changeIndex(this.index); }) } } }
四、成功展示
编辑:黄飞
全部0条评论
快来发表一下你的评论吧 !