成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

ArkUI如何實現(xiàn)增刪Tab頁簽

開發(fā) 前端
本文以瀏覽器中增加或刪除頁簽為例,實現(xiàn)Tabs中頁簽的增刪功能。整體布局分為兩部分:頁面內容和頁簽部分。

部分應用在使用過程中需要自定義添加或刪除標簽的場景,比如在瀏覽器中的頂部標簽欄中需要新打開或關閉網(wǎng)頁頁簽,而這種場景與Tabs組件效果類似,但Tabs組件不提供增加或刪除頁簽的功能,不能自由的增加刪除頁簽,需要開發(fā)者自己實現(xiàn)Tabs中增刪頁簽功能。本文以瀏覽器中增加或刪除頁簽為例,實現(xiàn)Tabs中頁簽的增刪功能。

效果呈現(xiàn)

如下動圖所示:

圖片

環(huán)境要求

本例基于以下環(huán)境開發(fā),開發(fā)者也可以基于其他適配的版本進行開發(fā):

  • IDE: DevEco Studio 4.0 Release
  • SDK: Ohos_sdk_public 4.0.10.13 (API Version 10 Release)

實現(xiàn)原理

本例涉及的關鍵特性以及實現(xiàn)方案如下:

  • 通過@Builder自定義封裝一個導航頁簽欄,并通過ForEach完成對Tabs組件的內容頁和導航頁簽欄的動態(tài)渲染。
  • 通過TabsController的changeIndex可實現(xiàn)頁面的跳轉,傳入的index是數(shù)組中對應的索引值。
  • 頁簽的增加通過數(shù)組的push方法,增加數(shù)組元素。
  • 刪除頁簽通過通過刪除頁面對應數(shù)組的索引值處的數(shù)據(jù)完成,刪除后頁面跳轉位置根據(jù)業(yè)務邏輯要求確定跳轉頁面對應的索引值。

開發(fā)步驟

整體布局分為兩部分:頁面內容和頁簽部分。頁面視圖部分使用Tabs,其中頁簽對應顯示的內容需要放入TabContent組件中。頁簽部分通過@Builder自定義封裝一個tabBar組件,放入Tabs中的tabBar屬性中。

頁面視圖代碼塊:

Tabs({ barPosition: BarPosition.Start, controller: this.controller }) {
  ForEach(this.tabArray, (item: number) => {
    TabContent() {
      Text('我是頁面 ' + item + " 的內容")
        .height('100%')
        .width('100%')
        .fontSize(30)
        .backgroundColor("#ffffffff")
    }.tabBar(this.Tab(item))
  }, (item: number) => item.toString() + util.generateRandomUUID())
}
.barMode(BarMode.Scrollable, { margin: 30 })
.onChange((index) => {
  this.focusIndex = index
})
.barHeight(30)

自定義tabBar代碼塊:

//控制頁簽渲染的數(shù)組
@State tabArray: Array<number> = [0]
//Tabs組件當前顯示的頁簽
@State focusIndex: number = 0
//創(chuàng)建頁簽時的頁簽index
@State pre: number = -1
//Tabs組件控制器,根據(jù)組件下標控制tab跳轉
private controller: TabsController = new TabsController()

//自定義導航頁簽欄
@Builder
Tab(tabNumber: number) {
  Row({ space: 20 }) {
    Text("頁簽 " + tabNumber).fontSize(18)
    Image($r('app.media.ic_public_cancel_filled')).width(20).height(20)
  }
  .justifyContent(FlexAlign.Center)
  .constraintSize({ minWidth: 35 })
  .width(120)
  .height(30)
  .borderRadius({ topLeft: 10, topRight: 10 })
  .backgroundColor(this.tabArray.indexOf(tabNumber) === this.focusIndex ? "#ffffffff" : "#ffb7b7b7")
}

實現(xiàn)頁簽和頁面視圖的聯(lián)動:這里主要通過TabsController的changeIndex來實現(xiàn)對應的試圖跳轉,但需要注意由于之后會增刪數(shù)組元素的操作,所以此處傳入的index值是選擇頁面的tabNumber在數(shù)組中的索引值。

this.focusIndex = this.tabArray.indexOf(tabNumber)

增添數(shù)組元素實現(xiàn)增加頁簽的效果:增添數(shù)組元素使用數(shù)組的push方法在tabArray添加數(shù)據(jù)即可,但由于此demo原始定義的數(shù)組是連續(xù)的自然數(shù),后續(xù)增刪數(shù)組會打亂原有順序,所以此處處理為先判斷最后一個元素的值再加1,由于TabBar的渲染是通過ForEach被@State修飾的數(shù)組,因此當tabArray中添加數(shù)據(jù)后系統(tǒng)會通知ForEach便利數(shù)組重新渲染頁面。

this.tabArray.push(this.tabArray[this.tabArray.length - 1] + 1)

通常在添加新頁面后,瀏覽器會將頁面跳轉到新添加的頁面,因此在向tabArray中完成數(shù)據(jù)推送后,需要將頁簽通過TabsController中的changeIndex方法跳轉到最后一個。

this.focusIndex = this.tabArray.length - 1
this.controller.changeIndex(this.focusIndex)

當用戶選擇另一個頁簽時,可通過自定義頁簽中通用事件onClick進行控制,當用戶點擊待選擇的頁簽后,獲取當前頁簽對應的下標,然后通過TabsController中的changeIndex方法進行跳轉,此外可以通過更改頁簽背景顏色標識被選中頁簽的。

.backgroundColor(this.tabArray.indexOf(tabNumber) === this.focusIndex ? "#ffffffff" : "#ffb7b7b7")
.onClick(() => {
  this.focusIndex = this.tabArray.indexOf(tabNumber)
  this.controller.changeIndex(this.focusIndex)
})

刪除頁面有三種情況(刪除不同位置的頁面)。

  • 第一種情況是被關閉頁面為最后一個頁面,且當前選中的頁面為最后一個頁面,如果當前被選中頁面是剛剛被其他頁面創(chuàng)建的情況,因此頁面需要跳回到創(chuàng)建被刪除頁簽的頁簽(邏輯參考chrome瀏覽器)
if (this.pre >= 0) {
  this.focusIndex = this.pre
} 
this.tabArray.splice(this.tabArray.indexOf(tabNumber), 1)

如果不是的話直接將當前顯示頁簽下下標設置為前一個頁簽下標,tabArray數(shù)組通過splice方法刪除頁簽,并通過TabsController完成跳轉,此外頁面只要有關閉操作,頁面就不可以跳回打開該頁面的頁面,即將 pre設置為-1。

this.focusIndex = this.focusIndex - 1
this.tabArray.splice(this.tabArray.indexOf(tabNumber), 1)
this.pre = -1
this.controller.changeIndex(this.focusIndex)
  • 第二種情況,當用戶當前選擇的不是最后一個標簽,然后直接刪除其他頁簽時,可以直接刪除刪除,但是需要重新計算當前選中頁簽在tabArray中的實時位置,到新注意需要排除用戶在最后一個頁簽刪除當前頁簽的情況。
//當前選擇頁面的對應數(shù)組中的數(shù)據(jù)值
let focusNumber = this.tabArray[this.focusIndex]
//用于判斷是否是用戶在最后一個頁簽刪除當前頁簽的情況
if (this.tabArray.indexOf(focusNumber) >= 0) {
  this.focusIndex = this.tabArray.indexOf(focusNumber)
}
this.controller.changeIndex(this.focusIndex)
  • 第三種情況,當用戶當前選擇的不是最后一個標簽,且刪除被選中頁面,直接刪除,然后通過TabsController完成跳轉,不需要額外操作。

說明

  • 由于Tabs組件中的導航頁簽欄會占滿屏幕,導致添加按鈕無法直接添加到與頁簽直接平齊的位置,因此通過層疊布局(Stack)的方式,將添加頁簽按鈕覆蓋到Tabs組件上,通過Stack中的對齊方式將添加按鈕調整到合適位置。
  • 用于Tabs添加或刪除子節(jié)點時,F(xiàn)orEach需要重新將所有頁簽進行重新渲染,如果在添加或刪除完頁簽后直接調用TabsController中的changeIndex進行跳轉,頁面無法調到指定頁簽。這是由于ForEach還未將組件渲染完成,將子組件掛載到Tabs中,因此建議通過setTimeOut延遲一段時間再進行跳轉,經(jīng)過驗證大概50ms后即可,開發(fā)者可再自行驗證。
setTimeout(() => {
  this.controller.changeIndex(this.focusIndex)
}, 50)

完整實例

完整示例代碼如下:

import util from '@ohos.util'

@Entry
@Component
struct Drag {
  //控制頁簽渲染的數(shù)組
  @State tabArray: Array<number> = [0]
  //Tabs組件當前顯示的頁簽下標
  @State focusIndex: number = 0
  //創(chuàng)建頁簽時的頁簽index
  @State pre: number = -1
  //Tabs組件控制器,根據(jù)組件下標控制tab跳轉
  private controller: TabsController = new TabsController()

  // 單獨的頁簽
  @Builder
  Tab(tabNumber: number) {
    Row({ space: 20 }) {
      Text("頁簽 " + tabNumber).fontSize(18)
      Image($r('app.media.ic_public_cancel_filled')).width(20).height(20).onClick(() => {
        //獲取Tabs組件當前顯示的頁簽中顯示的數(shù)字
        let focusNumber = this.tabArray[this.focusIndex]
        //被刪除的頁簽是否是當前選中的頁簽,且是最后一個頁簽
        if (this.focusIndex === this.tabArray.indexOf(tabNumber) && this.focusIndex == this.tabArray.length - 1) {
          //判斷是否需要跳回到創(chuàng)建該頁簽時的頁簽,如果不需要直接跳轉到前一個頁簽
          if (this.pre >= 0) {
            this.focusIndex = this.pre
          } else {
            this.focusIndex = this.focusIndex - 1
          }
        }
        this.tabArray.splice(this.tabArray.indexOf(tabNumber), 1)
        this.pre = -1
        //對應刪除頁面中的第二種情況
        if (this.tabArray.indexOf(focusNumber) >= 0) {
          this.focusIndex = this.tabArray.indexOf(focusNumber)
        }
        //設置50ms 延遲跳轉
        setTimeout(() => {
          this.controller.changeIndex(this.focusIndex)
        }, 50)
      })
    }
    .justifyContent(FlexAlign.Center)
    .constraintSize({ minWidth: 35 })
    .width(120)
    .height(30)
    .borderRadius({ topLeft: 10, topRight: 10 })
    .backgroundColor(this.tabArray.indexOf(tabNumber) === this.focusIndex ? "#ffffffff" : "#ffb7b7b7")
    .onClick(() => {
      this.focusIndex = this.tabArray.indexOf(tabNumber)
      setTimeout(() => {
        this.controller.changeIndex(this.focusIndex)
      }, 50)
    })
  }

  build() {
    Column() {
      Column() {
        // 頁簽
        // Row() {
        Stack() {
          Row({ space: 7 }) {
            //tabs
            Tabs({ barPosition: BarPosition.Start, controller: this.controller }) {
              ForEach(this.tabArray, (item: number) => {
                TabContent() {
                  Text('我是頁面 ' + item + " 的內容")
                    .height('100%')
                    .width('100%')
                    .fontSize(30)
                    .backgroundColor("#ffffffff")
                }.tabBar(this.Tab(item))
              }, (item: number) => item.toString() + util.generateRandomUUID())
            }
            .barMode(BarMode.Scrollable, { margin: 30 })
            .onChange((index) => {
              this.focusIndex = index
            })
            .barHeight(30)
          }.width("100%")

          Row() {
            Image($r('app.media.ic_public_add_filled')).onClick(() => {
              if (this.tabArray.length === 0) {
                this.tabArray.push(0)
                this.focusIndex = this.tabArray.length - 1
              } else {
                this.pre = this.focusIndex
                this.tabArray.push(this.tabArray[this.tabArray.length - 1] + 1)
                this.focusIndex = this.tabArray.length - 1
              }
              setTimeout(() => {
                this.controller.changeIndex(this.focusIndex)
              }, 50)
            }).width(20).height(20)
          }.height(30).width(30).backgroundColor("#ffb7b7b7")
          .justifyContent(FlexAlign.Center)
        }
        .alignContent(Alignment.TopEnd)
        .width('100%')
        .backgroundColor("#ffb7b7b7")
      }
      .alignItems(HorizontalAlign.Start)
      .width('100%')
    }
    .height('100%')
  }
}
責任編輯:姜華 來源: 鴻蒙開發(fā)者社區(qū)
相關推薦

2022-04-01 16:04:33

Harmonytabs容器鴻蒙

2023-12-11 17:15:05

應用開發(fā)波紋進度條ArkUI

2023-12-11 17:20:36

抽屜式導航ArkUI應用開發(fā)

2022-07-27 22:56:45

前端應用緩存qiankun

2022-07-04 16:34:46

流光按鈕Stack

2022-11-02 16:06:54

ArkUIETS

2022-10-24 14:49:54

ArkUI心電圖組件

2022-09-14 15:17:26

ArkUI鴻蒙

2022-07-26 14:40:42

ArkUIJS

2022-08-05 19:27:22

通用API鴻蒙

2022-07-20 15:24:47

ArkUI動畫效果項目開發(fā)

2022-03-03 18:49:56

HarmonyOS鴻蒙操作系統(tǒng)

2022-10-17 14:36:09

ArkUI虛擬搖桿組件

2024-06-13 08:15:00

2024-01-11 15:54:55

eTS語言TypeScript應用開發(fā)

2021-11-26 10:08:57

鴻蒙HarmonyOS應用

2022-05-27 14:55:34

canvas畫布鴻蒙

2009-12-03 18:39:02

PHP變量php_se

2020-07-20 07:46:01

程序員加簽驗簽

2011-03-28 09:56:03

存儲增刪操作
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 九色www | 欧美一区二区三区在线 | 日韩在线视频一区 | 超碰男人天堂 | 国产成人99av超碰超爽 | 中文字幕免费视频 | 一区二区视频在线 | 国产一二三区电影 | 99精品久久 | 欧美 中文字幕 | 欧美黑人一级爽快片淫片高清 | 国产精品高清一区二区三区 | 欧美精品久久久久 | 国产偷录视频叫床高潮对白 | 亚洲黄色片免费观看 | 久久亚洲精品久久国产一区二区 | 亚洲精品久久久蜜桃网站 | 欧美成人a∨高清免费观看 老司机午夜性大片 | av中文字幕在线播放 | 一区二区免费 | 免费国产视频 | 操久久 | 二区不卡| 亚洲精品自在在线观看 | 新av在线 | 国产精品视频一区二区三区四蜜臂 | 日韩一区二区三区在线 | 成人av免费在线观看 | 97在线超碰 | 国产原创在线观看 | 一级免费在线视频 | 在线第一页 | 狠狠干美女| 久久久网| www.五月天婷婷 | 免费成人在线网站 | 久久综合av | 国产欧美精品一区二区 | 亚洲av毛片 | 在线观看成年人视频 | 日韩精品一区二区三区免费视频 |