深入浅出学习eTs之电话提示功能实现

一、需求分析
相信大家都接过电话吧,咳咳,本节来模拟一个不喜欢接电话的小朋友,在切换界面上加上小红点,具体的通话界面之后可能会做
实现页面切换
不同页面显示不同内容
可显示角标(小红点)
二、控件介绍
(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@componentstruct 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); }) } } } 四、成功展示


投资人互怼 共享单车将迎来合并大结局?
高精度低能耗—国外标杆IMU分析
博通新一代GPS芯片定位精度30厘米以内适用城市及密林
华为AOC光线缆的分类及型号
入户皮线光缆的衰耗是怎么回事?
深入浅出学习eTs之电话提示功能实现
风头劲压iPhone 弯曲手机、可穿戴电子产品照亮2013
LiteOS-M内核队列的关键数据结构及关键算法
Neuchips与新思科技合作开展帮助降低进入人工智能领域的门槛
芯片是如何去定义的
MIT新研发“可编程水滴”,能够实现精准操控
针对锂离子/聚合物电池保护的高集成解决方案
2020年4月前苹果App都需使用iOS 13 SDK构建
天禄科技业绩下滑,推进TAC膜国产化研发
STM32低成本WiFi播放电路设计详解
健康码扫码测温一体机及健康码终端解决方案助力秋冬季疫情防控
2020年或将是L3自动驾驶整体发展路线能够确定下来的一年
怎样设计数字电路板可以获得最好的SI和EMC特性
大功率变频装置电压等级必须下降
德赛西威与杰发科技签订合作协议 助推国产汽车电子芯片发展