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

关键词:harmonyOS   鸿蒙开发  ArkTS  TabContent

使用场景:类微信底部导航栏,点击/左右滑动切换页面并加载数据

开发环境:ArkTS3.1  API9  Phone设备

HMOS Dev官方文档:文档中心

演示效果:

目录

完整Demo已提交至Gitee

搭建页面

自定义TabContent(往后翻有完整代码)

思路

开始

完整自定义tabs代码

页面切换后如何加载新数据

介绍

父子组件解释

开始

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


完整Demo已提交至Gitee,传送门:

鸿蒙ArkTS tabBar页签切换Demo: HarmonyOS鸿蒙ArkTS tabBar页签切换完整项目Demo

搭建页面

我这里用三个页面举例,新建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('首页',$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]

[图7]

[图8]

[图9]

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

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

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,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,controller: this.tabsController }) {
      TabContent() {
        Home({ timer:$HomeTimer })
      }.tabBar(this.TabBuilder('首页',$rawfile('tabs/home.png')))

      TabContent() {
        Info({ timer:$InfoTimer })
      }.tabBar(this.TabBuilder('信息',$rawfile('tabs/service.png')))

      TabContent() {
        Mine({ timer:$MineTimer })
      }.tabBar(this.TabBuilder('我的',$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%')
  }
}

原文地址:https://blog.csdn.net/weixin_44640245/article/details/134152475

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


文章浏览阅读1.4k次。被@Observed装饰的类,可以被观察到属性的变化;子组件中@ObjectLink装饰器装饰的状态变量用于接收@Observed装饰的类的实例,和父组件中对应的状态变量建立双向数据绑定。这个实例可以是数组中的被@Observed装饰的项,或者是class object中是属性,这个属性同样也需要被@Observed装饰。单独使用@Observed是没有任何作用的,需要搭配@ObjectLink或者@Prop使用。_鸿蒙ark对象数组
文章浏览阅读1k次。Harmony OS_harmonyos创建数据库
文章浏览阅读1.1k次,点赞25次,收藏23次。自定义组件Header.ets页面(子组件)//自定义组件@Component//组件声明private title:ResourceStr//接收的参数build(){Row() {index.ets(父组件)//导入自定义组件@Entry@Componentbuild() {Column() {/*** 1. 自定义组件调用-----自定义组件------* 2. 在调用的组件上设置样式*/ShopTitle({ title: '商品列表' })
文章浏览阅读952次,点赞11次,收藏25次。ArkUI是一套构建分布式应用界面的声明式UI开发框架。它使用极简的UI信息语法、丰富的UI组件、以及实时界面预览工具,帮助您提升移动应用界面开发效率30%。您只需使用一套ArkTS API,就能在Android、iOS、鸿蒙多个平台上提供生动而流畅的用户界面体验。_支持ios 安卓 鸿蒙next的跨平台方案
文章浏览阅读735次。​错误: 找不到符号符号: 变量 Layout_list_item位置: 类 ResourceTable_错误: 找不到符号 符号: 变量 resourcetable 位置: 类 mainabilityslice
文章浏览阅读941次,点赞23次,收藏21次。harmony ARKTS base64 加解密_鸿蒙 鸿蒙加解密算法库
文章浏览阅读860次,点赞21次,收藏24次。使用自定义布局,实现子组件自动换行功能。图1自定义布局的使用效果创建自定义布局的类,并继承ComponentContainer,添加构造方法。//如需支持xml创建自定义布局,必须添加该构造方法实现ComponentContainer.EstimateSizeListener接口,在onEstimateSize方法中进行测量。......@Override//通知子组件进行测量//关联子组件的索引与其布局数据idx++) {//测量自身。_鸿蒙javaui
文章浏览阅读917次,点赞25次,收藏25次。这里需要注意的是,真机需要使用华为侧提供的测试机,测试机中会安装纯鸿蒙的系统镜像,能够体验到完整的鸿蒙系统功能,纯鸿蒙应用目前还不能完美地在 HarmonyOS 4.0 的商用机侧跑起来。当前,真机调试需要使用华为侧提供的测试机,测试机中会安装纯鸿蒙的系统镜像,能够体验到完整的鸿蒙系统功能,纯鸿蒙应用目前还不能完美地在 HarmonyOS 4.0 的商用机侧跑起来。另外,由于样式的解析是基于组件文件的纬度的,因此样式文件只能应用于被其引用的组件文件中,而不能跨文件应用,并且样式文件也只支持类选择器。_鸿蒙 小程序
文章浏览阅读876次,点赞17次,收藏4次。2. HarmonyOS应用开发DevEcoStudio准备-1HUAWEI DevEco Studio为运行在HarmonyOS和OpenHarmony系统上的应用和服务(以下简称应用/服务)提供一站式的开发平台。
文章浏览阅读811次。此对象主要映射JSON数组数据,比如服务器传的数据是这样的。_arkts json
文章浏览阅读429次。鸿蒙小游戏-数字华容道_华为鸿蒙手机自带小游戏
文章浏览阅读1.1k次,点赞24次,收藏19次。Ability是应用/服务所具备的能力的抽象,一个Module可以包含一个或多个Ability。
文章浏览阅读846次。本文带大家使用MQTT协议连接华为IoT平台,使用的是E53_IA1 智慧农业扩展板与 BearPi-HM_Nano 开发主板_mqtt 如何对接第三方iot平台
文章浏览阅读567次。HarmonyOS_arkts卡片
文章浏览阅读1k次,点赞19次,收藏20次。ArkTS开发鸿蒙OS连接mongoDB(后端node.js)2024最新教程
文章浏览阅读1.2k次,点赞23次,收藏15次。HarmonyOS与OpenHarmony(1)本质上的不同是:HarmonyOS是鸿蒙操作系统,而OpenHarmony则是从开源项目。这里可以联想一下Android,比如小米手机在Android开源系统的基础上开发了MIUI的手机操作系统,HarmonyOS就类似于MIUI,OpenHarmony类似Android基础底座。(2)HarmonyOS:是双框架,内聚了AOSP(Android Open Source Project )和OpenHarmony等。_鸿蒙模拟器开了怎么跑代码
文章浏览阅读1.1k次,点赞21次,收藏21次。鸿蒙(HarmonyOS)项目方舟框架(ArkUI)之Navigation组件。
文章浏览阅读2k次。由于之前的哥们匆忙离职了,所以鸿蒙手表项目的新版本我临时接过来打包发布,基本上之前没有啥鸿蒙经验,但是一直是做Android开发的,在工作人员的指导下发现打包配置基本上和Android一样,所以这些都不是问题,这里记录一下使用过程中遇到的问题。!过程和遇到的问题基本上都讲解了,关机睡觉,打卡收工。_鸿蒙系统adb命令
文章浏览阅读7.3k次,点赞9次,收藏29次。39. 【多选题】_column和row容器中,设置子组件在主轴方向上的对齐格式
文章浏览阅读1.1k次,点赞13次,收藏24次。18.鸿蒙HarmonyOS App(JAVA)日期选择器-时间选择器点击button按钮显示月份与获取的时间。_harmonyos农历获取