一、需求分析
相信大家都接過電話吧,咳咳,本節(jié)來模擬一個不喜歡接電話的小朋友,在切換界面上加上小紅點,具體的通話界面之后可能會做
實現(xiàn)頁面切換
不同頁面顯示不同內(nèi)容
可顯示角標(小紅點)
二、控件介紹
(1)Tabs
一種可以通過頁簽進行內(nèi)容視圖切換的容器組件,每個頁簽對應一個內(nèi)容視圖。
說明:
該組件從API Version 7開始支持。后續(xù)版本如有新增內(nèi)容,則采用上角標單獨標記該內(nèi)容的起始版本。
Tabs(value?: {barPosition?: BarPosition, index?: number, controller?: TabsController})
參數(shù):
| 參數(shù)名 | 參數(shù)類型 | 必填 | 參數(shù)描述 |
|---|---|---|---|
| barPosition | BarPosition | 否 | 指定頁簽位置來創(chuàng)建Tabs容器組件。 默認值:BarPosition.Start |
| index | number | 否 | 指定初次初始頁簽索引。 默認值:0 |
| controller | TabsController | 否 | 設(shè)置Tabs控制器。 |
BarPosition枚舉說明
| 名稱 | 描述 |
|---|---|
| Start | vertical屬性方法設(shè)置為true時,頁簽位于容器左側(cè);vertical屬性方法設(shè)置為false時,頁簽位于容器頂部。 |
| End | vertical屬性方法設(shè)置為true時,頁簽位于容器右側(cè);vertical屬性方法設(shè)置為false時,頁簽位于容器底部。 |
屬性
不支持觸摸熱區(qū)設(shè)置,除支持通用屬性外,還支持以下屬性:
| 名稱 | 參數(shù)類型 | 描述 |
|---|---|---|
| vertical | boolean | 設(shè)置為false是為橫向Tabs,設(shè)置為true時為縱向Tabs。 默認值:false |
| scrollable | boolean | 設(shè)置為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中使用,對應一個切換頁簽的內(nèi)容視圖。
說明:
該組件從API Version 7開始支持。后續(xù)版本如有新增內(nèi)容,則采用上角標單獨標記該內(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è)置通用寬度屬性,其寬度默認撐滿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
可以附加在單個組件上用于信息標記的容器組件。
說明: 該組件從API Version 7開始支持。后續(xù)版本如有新增內(nèi)容,則采用上角標單獨標記該內(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è)計
(1)頁面切換
首先需要創(chuàng)建一個TabContent組件,實現(xiàn)頁面切換

@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() { // 自定義聯(lián)系人標簽
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() { // 自定義動態(tài)標簽
Column() {
Blank()
Image(this.index == 2 ? 'pages/icon_dynamic_selected.png' : 'pages/icon_dynamic_normal.png')
.size({width: 25, height: 25})
Text('動態(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('動態(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) => { // 頁面切換回調(diào)
this.index = index;
})
}
.width('100%')
.height('100%')
}
}
(2)圖標修改

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


(3)角標添加
這里加入傳統(tǒng)的角標顏色,小紅點來實現(xiàn),當前未接電話有14個

@Builder tabMessage() { // 自定義消息標簽
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文章
528瀏覽量
22944 -
ets
+關(guān)注
關(guān)注
0文章
20瀏覽量
1921 -
OpenHarmony
+關(guān)注
關(guān)注
33文章
3950瀏覽量
21032
發(fā)布評論請先 登錄
深入淺出學習eTs之電話提示功能實現(xiàn)
評論