鸿蒙 ArkTS Tabs组件实现类微信(可滑动的)tabBar页签切换页面功能


风晓
风晓 2024-01-09 14:44:41 49449 赞同 0 反对 0
分类: 资源
鸿蒙 ArkTS Tabs组件实现类微信(可滑动的)tabBar页签切换页面功能

搭建页面
我这里用三个页面举例,新建home、info、mine页面,创建components目录存放自定义Tabs组件,目录结构如下,我这里已经准备了6个图标图片存放在了resources/rawfile/tabs

 

自定义Tabs(附完整代码)
思路
index为应用加载的首页,加载自定义Tabs组件,Tabs组件中加载各个页面

开始
HMOS Dev官方文档 TabContent :文档中心

1.首先在index.est中导入自定义Tabs组件,避免与官方组件冲突取名comTabs

 

2.在自定义Tabs组件中导入所建的三个页面[如图3],记得在页面中使用export导出[如图4]

 

[左图3 | 右图4]

3.设置一个PAGE的枚举,增强可读性,不喜欢用就0123代替,因为页面切换的回调函数返回的数值从0开始,所以给currentIndex默认设置为0即为home页(@State装饰器修饰的属性当状态改变时,UI会发生对应的渲染改变),changePage自己写来用于更新页面数据函数,稍后会用到。别忘了new TabsController()[如图3]

4.官方提供了多种页签样式,我们使用置于底部的,将Tabs中barPosition属性设置为BarPosition.End。Tabs将占用整个页面,所以宽高需设置为100%。

Tabs组件中需要TabContent来加载页面。[如图5]

在tabBar中自定义页签按钮样式,因重复代码太多,我们可以利用@Builder装饰器来自定义构建函数复用代码。[如图6]

注意:自定义页签设置onClick事件用于改变页面索引,Tabs组件需设置onChange事件,不然页面左右滑动页签状态不会改变。

 

[图5]

 

[图6]  

完整自定义tabs代码
// tabs.ets
 
// home页
import Home from '../pages/home/home'
// info页
import Info from '../pages/info/info'
// mine页
import Mine from '../pages/mine/mine'
 
enum PAGE{
  HOME = 0,
  INFO = 1,
  MINE = 2
}
 
@Preview
@Component
export default  struct compTabs{
  @State currentIndex: number = 0;
  private tabsController: TabsController = new TabsController();
 
  changePage(e){
    this.currentIndex = e
    if (e == PAGE.HOME){
    }
    if (e == PAGE.INFO){
    }
    if (e == PAGE.MINE){
    }
  }
 
  @Builder TabBuilder(title: string, targetIndex: number, selectedImg: Resource, normalImg: Resource) {
    Column() {
      Image(this.currentIndex === targetIndex ? selectedImg : normalImg)
        .size({ width: 20, height: 20 }).objectFit(ImageFit.Fill)
      Text(title)
        .fontColor(this.currentIndex === targetIndex ? '#484D54' : '#ff969da9')
        .fontSize(10).margin({top:3,bottom:3})
    }
    .width('100%')
    .height(67)
    .alignItems(HorizontalAlign.Center)
    .backgroundColor('#fff')
    .justifyContent(FlexAlign.Center)
    .onClick(() => {
      this.currentIndex = targetIndex;
      this.tabsController.changeIndex(targetIndex);
    })
  }
 
  build() {
    Tabs({ barPosition: BarPosition.End, controller: this.tabsController }) {
      TabContent() {
        Home()
      }.tabBar(this.TabBuilder('首页', 0, $rawfile('tabs/home_a.png'), $rawfile('tabs/home.png')))
 
      TabContent() {
        Info()
      }.tabBar(this.TabBuilder('信息', 1, $rawfile('tabs/service_a.png'), $rawfile('tabs/service.png')))
 
      TabContent() {
        Mine()
      }.tabBar(this.TabBuilder('我的', 2, $rawfile('tabs/me_a.png'), $rawfile('tabs/me.png')))
    }.onChange((index: number) => {
      this.changePage(index)
    })
    .width('100%')
    .height('100%')
  }
}

页面切换后如何加载新数据
介绍
需要注意的是,在tabContent中不管有多少个页面都会被一次性加载完,切换页面不会达到页面更新的效果。那么页面切换后,如何加载页面的数据呢,很简单,可以利用官方提供的@Link装饰器(父子双向同步)向子组件传递一个时间戳参数过去,页面中使用@Watch监听这个时间戳属性的变化触发自定义的customShow函数。

或者可以增加 if 判断页面索引使其重新加载

父子组件解释
在上述的tabs讲述中导入了home页面、info页面、mine页面,那这三个页面就相当于是tabs的子组件了

开始
1.给子组件设置@Link修饰的timer属性(@Link修饰不用赋初值)

2.利用@watch监听一个自定义函数customShow,当父组件的这个timer改变时子组件就会触发这个函数[如图9]

3.父组件Tabs设置三个属性HomeTimer、InfoTimer、MineTimer,分别记录每个页面的时间戳,新增timeStamp函数返回当前时间戳,在changePage函数触发时获取最新的时间戳[如图7],TabContent中页面里传参时别忘了$符号[如图8]。

 

 

同样可以自定义页面的销毁等等,这是我在鸿蒙开发中最常用最省事最高效的办法了,大家不妨试试。

页面切换时可加载新数据的完整代码
Tabs.est

// Tabs.ets
 
// home页
import Home from '../pages/home/home'
// info页
import Info from '../pages/info/info'
// mine页
import Mine from '../pages/mine/mine'
 
enum PAGE{
  HOME = 0,
  INFO = 1,
  MINE = 2
}
 
@Preview
@Component
export default  struct compTabs{
  @State currentIndex: number = 0;
  @State HomeTimer: number = 0;
  @State InfoTimer: number = 0;
  @State MineTimer: number = 0;
  private tabsController: TabsController = new TabsController();
 
  changePage(e){
    this.currentIndex = e
    if (e == PAGE.HOME){
      this.HomeTimer = this.timeStamp()
    }
    if (e == PAGE.INFO){
      this.InfoTimer = this.timeStamp()
    }
    if (e == PAGE.MINE){
      this.MineTimer = this.timeStamp()
    }
  }
 
  timeStamp(){
    return new Date().getTime();
  }
 
  @Builder TabBuilder(title: string, targetIndex: number, selectedImg: Resource, normalImg: Resource) {
    Column() {
      Image(this.currentIndex === targetIndex ? selectedImg : normalImg)
        .size({ width: 20, height: 20 }).objectFit(ImageFit.Fill)
      Text(title)
        .fontColor(this.currentIndex === targetIndex ? '#484D54' : '#ff969da9')
        .fontSize(10).margin({top:3,bottom:3})
    }
    .width('100%')
    .height(67)
    .alignItems(HorizontalAlign.Center)
    .backgroundColor('#fff')
    .justifyContent(FlexAlign.Center)
    .onClick(() => {
      this.currentIndex = targetIndex;
      this.tabsController.changeIndex(targetIndex);
    })
  }
 
  build() {
    Tabs({ barPosition: BarPosition.End, controller: this.tabsController }) {
      TabContent() {
        Home({ timer:$HomeTimer })
      }.tabBar(this.TabBuilder('首页', 0, $rawfile('tabs/home_a.png'), $rawfile('tabs/home.png')))
 
      TabContent() {
        Info({ timer:$InfoTimer })
      }.tabBar(this.TabBuilder('信息', 1, $rawfile('tabs/service_a.png'), $rawfile('tabs/service.png')))
 
      TabContent() {
        Mine({ timer:$MineTimer })
      }.tabBar(this.TabBuilder('我的', 2, $rawfile('tabs/me_a.png'), $rawfile('tabs/me.png')))
    }.onChange((index: number) => {
      this.changePage(index)
    })
    .width('100%')
    .height('100%')
  }
}

home.est

import promptAction from '@ohos.promptAction';
 
@Component
export default struct Home {
  @State message: string = 'home页面'
  @Link @Watch('customShow') timer: Number
 
  customShow(){
    promptAction.showToast({
      message: "页面展示"
    });
  }
 
  build() {
    Row() {
      Column() {
        Text(this.message)
          .fontSize(50)
          .fontWeight(FontWeight.Bold)
      }
      .width('100%')
    }
    .height('100%')
  }
}

如果您发现该资源为电子书等存在侵权的资源或对该资源描述不正确等,可点击“私信”按钮向作者进行反馈;如作者无回复可进行平台仲裁,我们会在第一时间进行处理!

评价 0 条
风晓L1
粉丝 1 资源 2038 + 关注 私信
最近热门资源
银河麒麟桌面操作系统备份用户数据  123
统信桌面专业版【全盘安装UOS系统】介绍  116
银河麒麟桌面操作系统安装佳能打印机驱动方法  108
银河麒麟桌面操作系统 V10-SP1用户密码修改  101
最近下载排行榜
银河麒麟桌面操作系统备份用户数据 0
统信桌面专业版【全盘安装UOS系统】介绍 0
银河麒麟桌面操作系统安装佳能打印机驱动方法 0
银河麒麟桌面操作系统 V10-SP1用户密码修改 0
作者收入月榜
1

prtyaa 收益393.62元

2

zlj141319 收益217.85元

3

1843880570 收益214.2元

4

IT-feng 收益208.98元

5

风晓 收益208.24元

6

777 收益172.71元

7

Fhawking 收益106.6元

8

信创来了 收益105.84元

9

克里斯蒂亚诺诺 收益91.08元

10

技术-小陈 收益79.5元

请使用微信扫码

加入交流群

请使用微信扫一扫!