Tabs(頁面導(dǎo)航)

2024-01-25 13:20 更新

當(dāng)頁面信息較多時(shí),為了讓用戶能夠聚焦于當(dāng)前顯示的內(nèi)容,需要對頁面內(nèi)容進(jìn)行分類,提高頁面空間利用率。Tabs組件可以在一個(gè)頁面內(nèi)快速實(shí)現(xiàn)視圖內(nèi)容的切換,一方面提升查找信息的效率,另一方面精簡用戶單次獲取到的信息量。

基本布局

Tabs組件的頁面組成包含兩個(gè)部分,分別是TabContent和TabBar。TabContent是內(nèi)容頁,TabBar是導(dǎo)航頁簽欄,頁面結(jié)構(gòu)如下圖所示,根據(jù)不同的導(dǎo)航類型,布局會(huì)有區(qū)別,可以分為底部導(dǎo)航、頂部導(dǎo)航、側(cè)邊導(dǎo)航,其導(dǎo)航欄分別位于底部、頂部和側(cè)邊。
圖1 Tabs組件布局示意圖
說明
  • TabContent組件不支持設(shè)置通用寬度屬性,其寬度默認(rèn)撐滿Tabs父組件。
  • TabContent組件不支持設(shè)置通用高度屬性,其高度由Tabs父組件高度與TabBar組件高度決定。

Tabs使用花括號(hào)包裹TabContent,如圖2,其中TabContent顯示相應(yīng)的內(nèi)容頁。

圖2 Tabs與TabContent使用

每一個(gè)TabContent對應(yīng)的內(nèi)容需要有一個(gè)頁簽,可以通過TabContent的tabBar屬性進(jìn)行配置。在如下TabContent組件上設(shè)置屬性tabBar,可以設(shè)置其對應(yīng)頁簽中的內(nèi)容,tabBar作為內(nèi)容的頁簽。

  1. TabContent() {
  2. Text('首頁的內(nèi)容').fontSize(30)
  3. }
  4. .tabBar('首頁')

設(shè)置多個(gè)內(nèi)容時(shí),需在Tabs內(nèi)按照順序放置。

  1. Tabs() {
  2. TabContent() {
  3. Text('首頁的內(nèi)容').fontSize(30)
  4. }
  5. .tabBar('首頁')
  6. TabContent() {
  7. Text('推薦的內(nèi)容').fontSize(30)
  8. }
  9. .tabBar('推薦')
  10. TabContent() {
  11. Text('發(fā)現(xiàn)的內(nèi)容').fontSize(30)
  12. }
  13. .tabBar('發(fā)現(xiàn)')
  14. TabContent() {
  15. Text('我的內(nèi)容').fontSize(30)
  16. }
  17. .tabBar("我的")
  18. }

底部導(dǎo)航

底部導(dǎo)航是應(yīng)用中最常見的一種導(dǎo)航方式。底部導(dǎo)航位于應(yīng)用一級頁面的底部,用戶打開應(yīng)用,能夠分清整個(gè)應(yīng)用的功能分類,以及頁簽對應(yīng)的內(nèi)容,并且其位于底部更加方便用戶單手操作。底部導(dǎo)航一般作為應(yīng)用的主導(dǎo)航形式存在,其作用是將用戶關(guān)心的內(nèi)容按照功能進(jìn)行分類,迎合用戶使用習(xí)慣,方便在不同模塊間的內(nèi)容切換。

圖3 底部導(dǎo)航欄

導(dǎo)航欄位置使用Tabs的參數(shù)barPosition進(jìn)行設(shè)置,默認(rèn)情況下,導(dǎo)航欄位于頂部,參數(shù)默認(rèn)值為Start。設(shè)置為底部導(dǎo)航需要在Tabs傳遞參數(shù),設(shè)置barPosition為End。

  1. Tabs({ barPosition: BarPosition.End }) {
  2. // TabContent的內(nèi)容:首頁、發(fā)現(xiàn)、推薦、我的
  3. ...
  4. }

頂部導(dǎo)航

當(dāng)內(nèi)容分類較多,用戶對不同內(nèi)容的瀏覽概率相差不大,需要經(jīng)??焖偾袚Q時(shí),一般采用頂部導(dǎo)航模式進(jìn)行設(shè)計(jì),作為對底部導(dǎo)航內(nèi)容的進(jìn)一步劃分,常見一些資訊類應(yīng)用對內(nèi)容的分類為關(guān)注、視頻、數(shù)碼,或者手機(jī)的主題應(yīng)用中對主題進(jìn)行進(jìn)一步劃分為圖片、視頻、字體等。

圖4 頂部導(dǎo)航欄

Tabs組件默認(rèn)的barPosition參數(shù)為Start,即頂部導(dǎo)航模式。

  1. Tabs({ barPosition: BarPosition.Start }) {
  2. // TabContent的內(nèi)容:關(guān)注、視頻、游戲、數(shù)碼、科技、體育、影視
  3. ...
  4. }

側(cè)邊導(dǎo)航

側(cè)邊導(dǎo)航是手機(jī)應(yīng)用較為少見的一種導(dǎo)航模式,更多適用于平板橫屏界面,用于對應(yīng)用進(jìn)行導(dǎo)航操作,由于用戶的視覺習(xí)慣是從左到右,側(cè)邊導(dǎo)航欄默認(rèn)為左側(cè)側(cè)邊欄。

圖5 側(cè)邊導(dǎo)航欄

實(shí)現(xiàn)側(cè)邊導(dǎo)航欄需要設(shè)置Tabs的屬性vertical為true。在底部導(dǎo)航和頂部導(dǎo)航實(shí)現(xiàn)中,其默認(rèn)值為false,表明內(nèi)容頁和導(dǎo)航欄垂直方向排列。

  1. Tabs({ barPosition: BarPosition.Start }) {
  2. // TabContent的內(nèi)容:首頁、發(fā)現(xiàn)、推薦、我的
  3. ...
  4. }
  5. .vertical(true)
  6. .barWidth(100)
  7. .barHeight(200)
說明
  • vertical為false時(shí),tabbar寬度會(huì)默認(rèn)撐滿屏幕的寬度,需要設(shè)置barWidth為合適值。
  • vertical為true時(shí),tabbar的高度會(huì)默認(rèn)實(shí)際內(nèi)容高度,需要設(shè)置barHeight為合適值。

限制導(dǎo)航欄的滑動(dòng)切換

默認(rèn)情況下,導(dǎo)航欄都支持滑動(dòng)切換,在一些內(nèi)容信息量需要進(jìn)行多級分類的頁面,如支持底部導(dǎo)航+頂部導(dǎo)航組合的情況下,底部導(dǎo)航欄的滑動(dòng)效果與頂部導(dǎo)航出現(xiàn)沖突,此時(shí)需要限制底部導(dǎo)航的滑動(dòng),避免引起不好的用戶體驗(yàn)。
圖6 限制底部導(dǎo)航欄滑動(dòng)

控制滑動(dòng)切換的屬性為scrollable,默認(rèn)值為true,表示可以滑動(dòng),若要限制滑動(dòng)切換頁簽則需要設(shè)置為false。

  1. Tabs({ barPosition: BarPosition.End }) {
  2. TabContent(){
  3. Column(){
  4. Tabs(){
  5. // 頂部導(dǎo)航欄內(nèi)容
  6. ...
  7. }
  8. }
  9. .backgroundColor('#ff08a8f1')
  10. .width('100%')
  11. }
  12. .tabBar('首頁')
  13. // 其他TabContent內(nèi)容:發(fā)現(xiàn)、推薦、我的
  14. ...
  15. }
  16. .scrollable(false)

固定導(dǎo)航欄

當(dāng)內(nèi)容分類較為固定且不具有拓展性時(shí),例如底部導(dǎo)航內(nèi)容分類一般固定,分類數(shù)量一般在3-5個(gè),此時(shí)使用固定導(dǎo)航欄。固定導(dǎo)航欄不可滾動(dòng),無法被拖拽滾動(dòng),內(nèi)容均分tabBar的寬度。

圖7 固定導(dǎo)航欄

Tabs的屬性barMode是控制導(dǎo)航欄是否可以滾動(dòng),默認(rèn)值為Fixed。

  1. Tabs({ barPosition: BarPosition.End }) {
  2. // TabContent的內(nèi)容:首頁、發(fā)現(xiàn)、推薦、我的
  3. ...
  4. }
  5. .barMode(BarMode.Fixed)

滾動(dòng)導(dǎo)航欄

滾動(dòng)導(dǎo)航欄可以用于頂部導(dǎo)航欄或者側(cè)邊導(dǎo)航欄的設(shè)置,內(nèi)容分類較多,屏幕寬度無法容納所有分類頁簽的情況下,需要使用可滾動(dòng)的導(dǎo)航欄,支持用戶點(diǎn)擊和滑動(dòng)來加載隱藏的頁簽內(nèi)容。

圖8 可滾動(dòng)導(dǎo)航欄

滾動(dòng)導(dǎo)航欄需要設(shè)置Tabs組件的barMode屬性,默認(rèn)情況下其值為Fixed,表示為固定導(dǎo)航欄,設(shè)置為Scrollable即可設(shè)置為可滾動(dòng)導(dǎo)航欄。

  1. Tabs({ barPosition: BarPosition.Start }) {
  2. // TabContent的內(nèi)容:關(guān)注、視頻、游戲、數(shù)碼、科技、體育、影視、人文、藝術(shù)、自然、軍事
  3. ...
  4. }
  5. .barMode(BarMode.Scrollable)

自定義導(dǎo)航欄

對于底部導(dǎo)航欄,一般作為應(yīng)用主頁面功能區(qū)分,為了更好的用戶體驗(yàn),會(huì)組合文字以及對應(yīng)語義圖標(biāo)表示頁簽內(nèi)容,這種情況下,需要自定義導(dǎo)航頁簽的樣式。

圖9 自定義導(dǎo)航欄圖

系統(tǒng)默認(rèn)情況下采用了下劃線標(biāo)志當(dāng)前活躍的頁簽,而自定義導(dǎo)航欄需要自行實(shí)現(xiàn)相應(yīng)的樣式,用于區(qū)分當(dāng)前活躍頁簽和未活躍頁簽。

設(shè)置自定義導(dǎo)航欄需要使用tabBar的參數(shù),以其支持的CustomBuilder的方式傳入自定義的函數(shù)組件樣式。例如這里聲明TabBuilder的自定義函數(shù)組件,傳入?yún)?shù)包括頁簽文字title,對應(yīng)位置index,以及選中狀態(tài)和未選中狀態(tài)的圖片資源。通過當(dāng)前活躍的currentIndex和頁簽對應(yīng)的targetIndex匹配與否,決定UI顯示的樣式。

  1. @Builder TabBuilder(title: string, targetIndex: number, selectedImg: Resource, normalImg: Resource) {
  2. Column() {
  3. Image(this.currentIndex === targetIndex ? selectedImg : normalImg)
  4. .size({ width: 25, height: 25 })
  5. Text(title)
  6. .fontColor(this.currentIndex === targetIndex ? '#1698CE' : '#6B6B6B')
  7. }
  8. .width('100%')
  9. .height(50)
  10. .justifyContent(FlexAlign.Center)
  11. }

在TabContent對應(yīng)tabBar屬性中傳入自定義函數(shù)組件,并傳遞相應(yīng)的參數(shù)。

  1. TabContent() {
  2. Column(){
  3. Text('我的內(nèi)容')
  4. }
  5. .width('100%')
  6. .height('100%')
  7. .backgroundColor('#007DFF')
  8. }
  9. .tabBar(this.TabBuilder('我的', 0, $r('app.media.mine_selected'), $r('app.media.mine_normal')))

切換至指定頁簽

在不使用自定義導(dǎo)航欄時(shí),系統(tǒng)默認(rèn)的Tabs會(huì)實(shí)現(xiàn)切換邏輯。在使用了自定義導(dǎo)航欄后,切換頁簽的邏輯需要手動(dòng)實(shí)現(xiàn)。即用戶點(diǎn)擊對應(yīng)頁簽時(shí),屏幕需要顯示相應(yīng)的內(nèi)容頁。

圖10 使用自定義導(dǎo)航欄實(shí)現(xiàn)切換指定頁簽

切換指定頁簽需要使用TabsController,TabsController是Tabs組件的控制器,用于控制Tabs組件進(jìn)行頁簽切換。通過TabsController的changeIndex方法來實(shí)現(xiàn)跳轉(zhuǎn)至指定索引值對應(yīng)的TabContent內(nèi)容。

  1. private tabsController : TabsController = new TabsController()
  2. @State currentIndex:number = 0;
  3. @Builder TabBuilder(title: string, targetIndex: number) {
  4. Column() {
  5. Text(title)
  6. .fontColor(this.currentIndex === targetIndex ? '#1698CE' : '#6B6B6B')
  7. }
  8. ...
  9. .onClick(() => {
  10. this.currentIndex = targetIndex;
  11. this.tabsController.changeIndex(this.currentIndex);
  12. })
  13. }

使用自定義導(dǎo)航欄時(shí),在tabBar屬性中傳入對應(yīng)的@Builder,并傳入相應(yīng)的參數(shù)。

  1. Tabs({ barPosition: BarPosition.End, controller: this.tabsController }) {
  2. TabContent(){
  3. ...
  4. }.tabBar(this.TabBuilder('首頁',0))
  5. TabContent(){
  6. ...
  7. }.tabBar(this.TabBuilder('發(fā)現(xiàn)',1))
  8. TabContent(){
  9. ...
  10. }.tabBar(this.TabBuilder('推薦',2))
  11. TabContent(){
  12. ...
  13. }
  14. .tabBar(this.TabBuilder('我的',3))
  15. }

滑動(dòng)切換導(dǎo)航欄

在不使用自定義導(dǎo)航欄的情況下,Tabs默認(rèn)會(huì)實(shí)現(xiàn)tabBar與TabContent的切換聯(lián)動(dòng)。但在使用了自定義導(dǎo)航欄后,使用TabsController可以實(shí)現(xiàn)點(diǎn)擊頁簽與頁面內(nèi)容的聯(lián)動(dòng),但不能實(shí)現(xiàn)滑動(dòng)頁面時(shí),頁面內(nèi)容對應(yīng)頁簽的聯(lián)動(dòng)。即用戶在使用滑動(dòng)屏幕切換頁面內(nèi)容時(shí),頁簽欄需要同步切換至內(nèi)容對應(yīng)的頁簽。

圖11 滑動(dòng)切換時(shí)頁簽內(nèi)容不聯(lián)動(dòng)

此時(shí)需要使用Tabs提供的onChange事件方法,監(jiān)聽索引index的變化,并將其當(dāng)前活躍的index值傳遞給currentIndex,實(shí)現(xiàn)頁簽內(nèi)容的切換。

  1. Tabs({ barPosition: BarPosition.End, controller: this.tabsController }) {
  2. TabContent() {
  3. ...
  4. }.tabBar(this.TabBuilder('首頁', 0))
  5. TabContent() {
  6. ...
  7. }.tabBar(this.TabBuilder('發(fā)現(xiàn)', 1))
  8. TabContent() {
  9. ...
  10. }.tabBar(this.TabBuilder('推薦', 2))
  11. TabContent() {
  12. ...
  13. }
  14. .tabBar(this.TabBuilder('我的', 3))
  15. }.onChange((index) => {
  16. this.currentIndex = index
  17. })
圖12 內(nèi)容與頁簽聯(lián)動(dòng)
以上內(nèi)容是否對您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號(hào)
微信公眾號(hào)

編程獅公眾號(hào)