一、需求分析
相信大家都接過電話吧,咳咳,本節(jié)來模擬一個(gè)不喜歡接電話的小朋友,在切換界面上加上小紅點(diǎn),具體的通話界面之后可能會(huì)做
實(shí)現(xiàn)頁(yè)面切換
不同頁(yè)面顯示不同內(nèi)容
可顯示角標(biāo)(小紅點(diǎn))
二、控件介紹
(1)Tabs
一種可以通過頁(yè)簽進(jìn)行內(nèi)容視圖切換的容器組件,每個(gè)頁(yè)簽對(duì)應(yīng)一個(gè)內(nèi)容視圖。
說明:
該組件從API Version 7開始支持。后續(xù)版本如有新增內(nèi)容,則采用上角標(biāo)單獨(dú)標(biāo)記該內(nèi)容的起始版本。
Tabs(value?: {barPosition?: BarPosition, index?: number, controller?: TabsController})
參數(shù):
| 參數(shù)名 | 參數(shù)類型 | 必填 | 參數(shù)描述 |
|---|---|---|---|
| barPosition | BarPosition | 否 | 指定頁(yè)簽位置來創(chuàng)建Tabs容器組件。 默認(rèn)值:BarPosition.Start |
| index | number | 否 | 指定初次初始頁(yè)簽索引。 默認(rèn)值:0 |
| controller | TabsController | 否 | 設(shè)置Tabs控制器。 |
BarPosition枚舉說明
| 名稱 | 描述 |
|---|---|
| Start | vertical屬性方法設(shè)置為true時(shí),頁(yè)簽位于容器左側(cè);vertical屬性方法設(shè)置為false時(shí),頁(yè)簽位于容器頂部。 |
| End | vertical屬性方法設(shè)置為true時(shí),頁(yè)簽位于容器右側(cè);vertical屬性方法設(shè)置為false時(shí),頁(yè)簽位于容器底部。 |
屬性
不支持觸摸熱區(qū)設(shè)置,除支持通用屬性外,還支持以下屬性:
| 名稱 | 參數(shù)類型 | 描述 |
|---|---|---|
| vertical | boolean | 設(shè)置為false是為橫向Tabs,設(shè)置為true時(shí)為縱向Tabs。 默認(rèn)值:false |
| scrollable | boolean | 設(shè)置為true時(shí)可以通過滑動(dòng)頁(yè)面進(jìn)行頁(yè)面切換,為false時(shí)不可滑動(dòng)切換頁(yè)面。 默認(rèn)值:true |
| barMode | BarMode | TabBar布局模式,具體描述見BarMode枚舉說明。 默認(rèn)值:BarMode.Fixed |
| barWidth | number | Length8+ | TabBar的寬度值。 |
| barHeight | number | Length8+ | TabBar的高度值。 |
| animationDuration | number | TabContent滑動(dòng)動(dòng)畫時(shí)長(zhǎng)。 默認(rèn)值:200 |
BarMode枚舉說明
| 名稱 | 描述 |
|---|---|
| Scrollable | TabBar使用實(shí)際布局寬度, 超過總長(zhǎng)度后可滑動(dòng)。 |
| Fixed | 所有TabBar平均分配寬度。 |

(2)TabContentOpenAtom OpenHarmony
僅在Tabs中使用,對(duì)應(yīng)一個(gè)切換頁(yè)簽的內(nèi)容視圖。
說明:
該組件從API Version 7開始支持。后續(xù)版本如有新增內(nèi)容,則采用上角標(biāo)單獨(dú)標(biāo)記該內(nèi)容的起始版本。
屬性
除支持通用屬性外,還支持以下屬性:
| 名稱 | 參數(shù)類型 | 描述 |
|---|---|---|
| tabBar | string | Resource | { icon?: string | Resource, text?: string | Resource } | CustomBuilder8+ | 設(shè)置TabBar上顯示內(nèi)容。 CustomBuilder: 構(gòu)造器,內(nèi)部可以傳入組件(API8版本以上適用)。 > 說明: > 如果icon采用svg格式圖源,則要求svg圖源刪除其自有寬高屬性值。如采用帶有自有寬高屬性的svg圖源,icon大小則是svg本身內(nèi)置的寬高屬性值大小。 |
說明:
TabContent組件不支持設(shè)置通用寬度屬性,其寬度默認(rèn)撐滿Tabs父組件。
TabContent組件不支持設(shè)置通用高度屬性,其高度由Tabs父組件高度與TabBar組件高度決定。
TabContent組件不支持觸摸熱區(qū)設(shè)置。

// 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
可以附加在單個(gè)組件上用于信息標(biāo)記的容器組件。
說明: 該組件從API Version 7開始支持。后續(xù)版本如有新增內(nèi)容,則采用上角標(biāo)單獨(dú)標(biāo)記該內(nèi)容的起始版本。
Badge({
value: ' ',
position: BadgePosition.Left, // 設(shè)置 badge 居左顯示
style: {badgeSize: 10, badgeColor: Color.Red}// 設(shè)置 badge 的顯示樣式
}) {
Text("Badge")
.size({width: 100, height: 50})
.fontSize(20)
.backgroundColor("#aabbcc")
}
.size({width: 100, height: 50})
Badge({
value: ' ',
position: BadgePosition.Right, // 設(shè)置 badge 居右顯示
style: {badgeSize: 10, badgeColor: Color.Red}// 設(shè)置 badge 的顯示樣式
}) {
Text("Badge")
.size({width: 100, height: 50})
.fontSize(20)
.backgroundColor("#aabbcc")
}
.size({width: 100, height: 50})
Badge({
value: ' ',
position: BadgePosition.RightTop, // 設(shè)置 badge 居右上角顯示
style: {badgeSize: 10, badgeColor: Color.Red}// 設(shè)置 badge 的顯示樣式
}) {
Text("Badge")
.size({width: 100, height: 50})
.fontSize(20)
.backgroundColor("#aabbcc")
}
.size({width: 100, height: 50})

三、UI設(shè)計(jì)
(1)頁(yè)面切換
首先需要?jiǎng)?chuàng)建一個(gè)TabContent組件,實(shí)現(xiàn)頁(yè)面切換

@Entry @Component struct TabsTest {
private controller: TabsController = new TabsController();
@State index: number = 0; // 選項(xiàng)卡下標(biāo),默認(rèn)為第一個(gè)
@Builder tabMessage() { // 自定義消息標(biāo)簽
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() { // 自定義聯(lián)系人標(biāo)簽
Column() {
Blank()
Image(this.index == 1 ? 'pages/icon_contract_selected.png' : 'pages/icon_contract_normal.png')
.size({width: 25, height: 25})
Text('聯(lián)系人')
.fontSize(16)
.fontColor(this.index == 1 ? "#2a58d0" : "#6b6b6b")
Blank()
}
.height('100%')
.width("100%")
.onClick(() => {
this.index = 1;
this.controller.changeIndex(this.index);
})
}
@Builder tabDynamic() { // 自定義動(dòng)態(tài)標(biāo)簽
Column() {
Blank()
Image(this.index == 2 ? 'pages/icon_dynamic_selected.png' : 'pages/icon_dynamic_normal.png')
.size({width: 25, height: 25})
Text('動(dòng)態(tài)')
.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('聯(lián)系人')
.fontSize(30)
}
.width('100%')
.height('100%')
.backgroundColor("#bbccaa")
}
.tabBar(this.tabContract) // 使用自定義TabBar
TabContent() {
Column() {
Text('動(dòng)態(tài)')
.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) => { // 頁(yè)面切換回調(diào)
this.index = index;
})
}
.width('100%')
.height('100%')
}
}
(2)圖標(biāo)修改

在Tab組件中,圖標(biāo)需要選擇兩種風(fēng)格,一個(gè)是沒有點(diǎn)擊到的,另一個(gè)是被選中的狀態(tài),我這里使用本色和紅色來演示


(3)角標(biāo)添加
這里加入傳統(tǒng)的角標(biāo)顏色,小紅點(diǎn)來實(shí)現(xiàn),當(dāng)前未接電話有14個(gè)

@Builder tabMessage() { // 自定義消息標(biāo)簽
Badge({
count: 14, // 設(shè)置 badge 顯示的數(shù)量
maxCount: 100, // 設(shè)置 badge 顯示的最大數(shù)量
position: BadgePosition.RightTop,// 設(shè)置 badge 顯示在右上角
style: {badgeColor: Color.Red,fontSize:15,badgeSize:30} // 設(shè)置 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);
})
}
}
}
四、成功展示

編輯:黃飛
-
容器
+關(guān)注
關(guān)注
0文章
521瀏覽量
22750 -
ets
+關(guān)注
關(guān)注
0文章
20瀏覽量
1870 -
OpenHarmony
+關(guān)注
關(guān)注
31文章
3897瀏覽量
20495
發(fā)布評(píng)論請(qǐng)先 登錄
#深入淺出學(xué)習(xí)eTs#(八)“猜大小”小游戲
#深入淺出學(xué)習(xí)eTs#(十)藍(lán)藥丸還是紅藥丸
#深入淺出學(xué)習(xí)eTs#(一)模擬器/真機(jī)環(huán)境搭建
#深入淺出學(xué)習(xí)eTs#(二)拖拽式UI
#深入淺出學(xué)習(xí)eTs#(七)判斷密碼是否正確
#深入淺出學(xué)習(xí)eTs#(十一)別忘了吃藥喔
深入淺出學(xué)習(xí)eTs(一)模擬器/真機(jī)環(huán)境搭建
深入淺出學(xué)習(xí)eTs(七)如何判斷密碼是否正確
深入淺出學(xué)習(xí)eTs之九宮格密碼鎖功能實(shí)現(xiàn)

深入淺出學(xué)習(xí)eTs之電話提示功能實(shí)現(xiàn)
評(píng)論