日韩成人免费在线_国产成人一二_精品国产免费人成电影在线观..._日本一区二区三区久久久久久久久不

當(dāng)前位置:首頁(yè) > 科技  > 軟件

ArkUI如何實(shí)現(xiàn)增刪Tab頁(yè)簽

來(lái)源: 責(zé)編: 時(shí)間:2024-05-16 09:00:50 160觀看
導(dǎo)讀部分應(yīng)用在使用過(guò)程中需要自定義添加或刪除標(biāo)簽的場(chǎng)景,比如在瀏覽器中的頂部標(biāo)簽欄中需要新打開或關(guān)閉網(wǎng)頁(yè)頁(yè)簽,而這種場(chǎng)景與Tabs組件效果類似,但Tabs組件不提供增加或刪除頁(yè)簽的功能,不能自由的增加刪除頁(yè)簽,需要開發(fā)者自

sC728資訊網(wǎng)——每日最新資訊28at.com

部分應(yīng)用在使用過(guò)程中需要自定義添加或刪除標(biāo)簽的場(chǎng)景,比如在瀏覽器中的頂部標(biāo)簽欄中需要新打開或關(guān)閉網(wǎng)頁(yè)頁(yè)簽,而這種場(chǎng)景與Tabs組件效果類似,但Tabs組件不提供增加或刪除頁(yè)簽的功能,不能自由的增加刪除頁(yè)簽,需要開發(fā)者自己實(shí)現(xiàn)Tabs中增刪頁(yè)簽功能。本文以瀏覽器中增加或刪除頁(yè)簽為例,實(shí)現(xiàn)Tabs中頁(yè)簽的增刪功能。sC728資訊網(wǎng)——每日最新資訊28at.com

效果呈現(xiàn)

如下動(dòng)圖所示:sC728資訊網(wǎng)——每日最新資訊28at.com

圖片sC728資訊網(wǎng)——每日最新資訊28at.com

環(huán)境要求

本例基于以下環(huán)境開發(fā),開發(fā)者也可以基于其他適配的版本進(jìn)行開發(fā):sC728資訊網(wǎng)——每日最新資訊28at.com

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

實(shí)現(xiàn)原理

本例涉及的關(guān)鍵特性以及實(shí)現(xiàn)方案如下:sC728資訊網(wǎng)——每日最新資訊28at.com

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

開發(fā)步驟

整體布局分為兩部分:頁(yè)面內(nèi)容和頁(yè)簽部分。頁(yè)面視圖部分使用Tabs,其中頁(yè)簽對(duì)應(yīng)顯示的內(nèi)容需要放入TabContent組件中。頁(yè)簽部分通過(guò)@Builder自定義封裝一個(gè)tabBar組件,放入Tabs中的tabBar屬性中。sC728資訊網(wǎng)——每日最新資訊28at.com

頁(yè)面視圖代碼塊:sC728資訊網(wǎng)——每日最新資訊28at.com

Tabs({ barPosition: BarPosition.Start, controller: this.controller }) {  ForEach(this.tabArray, (item: number) => {    TabContent() {      Text('我是頁(yè)面 ' + item + " 的內(nèi)容")        .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代碼塊:sC728資訊網(wǎng)——每日最新資訊28at.com

//控制頁(yè)簽渲染的數(shù)組@State tabArray: Array<number> = [0]//Tabs組件當(dāng)前顯示的頁(yè)簽@State focusIndex: number = 0//創(chuàng)建頁(yè)簽時(shí)的頁(yè)簽index@State pre: number = -1//Tabs組件控制器,根據(jù)組件下標(biāo)控制tab跳轉(zhuǎn)private controller: TabsController = new TabsController()//自定義導(dǎo)航頁(yè)簽欄@BuilderTab(tabNumber: number) {  Row({ space: 20 }) {    Text("頁(yè)簽 " + 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")}

實(shí)現(xiàn)頁(yè)簽和頁(yè)面視圖的聯(lián)動(dòng):這里主要通過(guò)TabsController的changeIndex來(lái)實(shí)現(xiàn)對(duì)應(yīng)的試圖跳轉(zhuǎn),但需要注意由于之后會(huì)增刪數(shù)組元素的操作,所以此處傳入的index值是選擇頁(yè)面的tabNumber在數(shù)組中的索引值。sC728資訊網(wǎng)——每日最新資訊28at.com

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

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

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

通常在添加新頁(yè)面后,瀏覽器會(huì)將頁(yè)面跳轉(zhuǎn)到新添加的頁(yè)面,因此在向tabArray中完成數(shù)據(jù)推送后,需要將頁(yè)簽通過(guò)TabsController中的changeIndex方法跳轉(zhuǎn)到最后一個(gè)。sC728資訊網(wǎng)——每日最新資訊28at.com

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

當(dāng)用戶選擇另一個(gè)頁(yè)簽時(shí),可通過(guò)自定義頁(yè)簽中通用事件onClick進(jìn)行控制,當(dāng)用戶點(diǎn)擊待選擇的頁(yè)簽后,獲取當(dāng)前頁(yè)簽對(duì)應(yīng)的下標(biāo),然后通過(guò)TabsController中的changeIndex方法進(jìn)行跳轉(zhuǎn),此外可以通過(guò)更改頁(yè)簽背景顏色標(biāo)識(shí)被選中頁(yè)簽的。sC728資訊網(wǎng)——每日最新資訊28at.com

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

刪除頁(yè)面有三種情況(刪除不同位置的頁(yè)面)。sC728資訊網(wǎng)——每日最新資訊28at.com

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

如果不是的話直接將當(dāng)前顯示頁(yè)簽下下標(biāo)設(shè)置為前一個(gè)頁(yè)簽下標(biāo),tabArray數(shù)組通過(guò)splice方法刪除頁(yè)簽,并通過(guò)TabsController完成跳轉(zhuǎn),此外頁(yè)面只要有關(guān)閉操作,頁(yè)面就不可以跳回打開該頁(yè)面的頁(yè)面,即將 pre設(shè)置為-1。sC728資訊網(wǎng)——每日最新資訊28at.com

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

說(shuō)明

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

完整實(shí)例

完整示例代碼如下:

import util from '@ohos.util'@Entry@Componentstruct Drag {  //控制頁(yè)簽渲染的數(shù)組  @State tabArray: Array<number> = [0]  //Tabs組件當(dāng)前顯示的頁(yè)簽下標(biāo)  @State focusIndex: number = 0  //創(chuàng)建頁(yè)簽時(shí)的頁(yè)簽index  @State pre: number = -1  //Tabs組件控制器,根據(jù)組件下標(biāo)控制tab跳轉(zhuǎn)  private controller: TabsController = new TabsController()  // 單獨(dú)的頁(yè)簽  @Builder  Tab(tabNumber: number) {    Row({ space: 20 }) {      Text("頁(yè)簽 " + tabNumber).fontSize(18)      Image($r('app.media.ic_public_cancel_filled')).width(20).height(20).onClick(() => {        //獲取Tabs組件當(dāng)前顯示的頁(yè)簽中顯示的數(shù)字        let focusNumber = this.tabArray[this.focusIndex]        //被刪除的頁(yè)簽是否是當(dāng)前選中的頁(yè)簽,且是最后一個(gè)頁(yè)簽        if (this.focusIndex === this.tabArray.indexOf(tabNumber) && this.focusIndex == this.tabArray.length - 1) {          //判斷是否需要跳回到創(chuàng)建該頁(yè)簽時(shí)的頁(yè)簽,如果不需要直接跳轉(zhuǎn)到前一個(gè)頁(yè)簽          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        //對(duì)應(yīng)刪除頁(yè)面中的第二種情況        if (this.tabArray.indexOf(focusNumber) >= 0) {          this.focusIndex = this.tabArray.indexOf(focusNumber)        }        //設(shè)置50ms 延遲跳轉(zhuǎn)        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() {        // 頁(yè)簽        // Row() {        Stack() {          Row({ space: 7 }) {            //tabs            Tabs({ barPosition: BarPosition.Start, controller: this.controller }) {              ForEach(this.tabArray, (item: number) => {                TabContent() {                  Text('我是頁(yè)面 ' + item + " 的內(nèi)容")                    .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%')  }}

本文鏈接:http://www.www897cc.com/showinfo-26-88313-0.htmlArkUI如何實(shí)現(xiàn)增刪Tab頁(yè)簽

聲明:本網(wǎng)頁(yè)內(nèi)容旨在傳播知識(shí),若有侵權(quán)等問(wèn)題請(qǐng)及時(shí)與本網(wǎng)聯(lián)系,我們將在第一時(shí)間刪除處理。郵件:2376512515@qq.com

上一篇: SpringBoot項(xiàng)目中這10個(gè)開發(fā)技巧你都知道嗎?

下一篇: 盤點(diǎn)GoLang中的三方庫(kù):fsnotify、Viper、Logrus、Carbon

標(biāo)簽:
  • 熱門焦點(diǎn)
Top 主站蜘蛛池模板: 涿州市| 云和县| 扎鲁特旗| 平罗县| 淮南市| 盐山县| 钟祥市| 高邮市| 内乡县| 都昌县| 香港 | 金平| 江陵县| 宝丰县| 衡水市| 桂阳县| 抚宁县| 建德市| 白玉县| 高陵县| 阳城县| 巴里| 镇沅| 外汇| 湟中县| 龙口市| 化州市| 永顺县| 麻城市| 嘉禾县| 安阳市| 磐安县| 朝阳县| 通河县| 太仆寺旗| 图木舒克市| 周至县| 安徽省| 图片| 驻马店市| 鸡东县|