鸿蒙开发之多样化底部导航栏05——显隐导航栏
·
一、前言
在上一讲的鸿蒙开发之多样化底部导航栏04——悬浮导航栏中,我们把导航栏悬浮了起来。可是有时这个导航栏会挡住页面的一些内容,这时候我们就会想到要不要在某些条件下,让导航栏显示/隐藏起来?那办法肯定是有的,请看下面的预览效果。
预览效果
二、正题
本文中的悬浮导航栏我们的方案是当页面向上滑动时,让导航栏隐藏,向下滑动时让导航栏显示,该代码在项目路径:src/main/ets/pages/5-HiddenTabbar.ets
1、核心组件
系统库组件:
-
Tabs
2、核心代码
2.1 添加显隐变量
首先要有记录这个状态的变量,因为是上下两个方向,所以只需要用boolean值就行。默认为false,也就是不隐藏。
@State isHide: boolean = false;
2.2 页面操作
在首页的内容页面我们添加了List组件,它默认是可以滚动的,而且它的属性onScrollIndex()里面的参数就可以很好的让我们判断滑动方向。总共三个number类型参数:start、end和center,从字母意思就知道它们代表的什么意思。当前我们只需要用到start参数,如果以后大家碰到复杂的操作,可以适量使用三个参数来判断。
.onScrollIndex((firstIndex) => {
if (firstIndex > this.lastFirstIndex) {
this.isHide = true
} else if (firstIndex < this.lastFirstIndex) {
this.isHide = false
}
this.lastFirstIndex = firstIndex
})
三、完整代码
import { promptAction } from '@kit.ArkUI';
export class TabBarDataType {
id: number;
title: ResourceStr;
selectedIcon: ResourceStr;
defaultIcon: ResourceStr;
constructor(id: number, title: ResourceStr, selectedIcon: ResourceStr, defaultIcon: ResourceStr) {
this.id = id;
this.title = title;
this.selectedIcon = selectedIcon;
this.defaultIcon = defaultIcon;
}
}
const PUBLISH_TAB_BAR_INDEX: number = 1; // 初始化社区的tab下标
const TABINFO: TabBarDataType[] = [
new TabBarDataType(0, '首页', $r("app.media.ic_tabbar_home_on"), $r("app.media.ic_tabbar_home_off")),
new TabBarDataType(1, '发布', $r("app.media.ic_tabbar_publish_on"), $r("app.media.ic_tabbar_publish_off")),
new TabBarDataType(2, '我的', $r("app.media.ic_tabbar_my_on"), $r("app.media.ic_tabbar_my_off")),
];
@Entry
@Component
export struct HiddenTabbar {
@State isHide: boolean = false;
@Provide selectedIndex: number = 0; // 初始化被选定的tabBar下标
private controller: TabsController = new TabsController(); // 初始化Tab控制器
private arr: number[] = new Array(20).fill(0); // 生成20个0的数组
@State lastFirstIndex: number = 0
build() {
Stack({ alignContent: Alignment.Bottom }) {
Tabs({ index: this.selectedIndex, barPosition: BarPosition.End, controller: this.controller }) {
TabContent() {
List({ space: 20 }) {
ForEach(this.arr, (item: number, index: number) => {
ListItem() {
Text('向上滑动')
.fontSize(30)
}
})
}
.width('100%')
.height('100%')
.backgroundColor('#00CB87')
.alignListItem(ListItemAlign.Center)
.onScrollIndex((firstIndex) => {
if (firstIndex > this.lastFirstIndex) {
this.isHide = true
} else if (firstIndex < this.lastFirstIndex) {
this.isHide = false
}
this.lastFirstIndex = firstIndex
})
}
TabContent() {
// 占个位置而已
}
TabContent() {
Column() {
Text('我的内容')
.fontSize(30)
}
.width('100%')
.height('100%')
.backgroundColor('#E67C92')
.justifyContent(FlexAlign.Center)
}
}
.barHeight(0)
.vertical(false)
.scrollable(false)
.layoutWeight(1)
.onChange((index: number) => {
this.selectedIndex = index;
})
// 自定义TabBar组件
CustomTabBar({ selectedIndex: $selectedIndex })
.margin({ left: 20, right: 20 })
.borderRadius(20)
.offset({ y: -10 })
.backgroundColor($r('app.color.tab_bar_background'))
.visibility(this.isHide ? Visibility.Hidden : Visibility.Visible)
.animation({
duration: 300,
curve: Curve.Ease,
iterations: 1,
playMode: PlayMode.Normal
})
}
.width('100%')
.height('100%')
.borderRadius(8)
// .backgroundColor(Color.Pink)
}
}
@Component
struct CustomTabBar {
@Link selectedIndex: number; // 初始化被选定的tabBar下标
@State iconOffset: number = 0; // 初始化tabBar图片的偏移量
aboutToAppear(): void {
this.iconOffset = -3 // 应用启动后,给被选中的按钮抬升3vp
}
build() {
Flex({ direction: FlexDirection.Row, justifyContent: FlexAlign.SpaceAround, alignItems: ItemAlign.Center }) {
ForEach(TABINFO, (item: TabBarDataType, tabIndex: number) => {
TabItem({
iconOffset: this.iconOffset,
tabBarIndex: tabIndex,
selectedIndex: $selectedIndex,
})
})
}
}
}
@Component
struct TabItem {
@Prop iconOffset: number; // 初始化tabBar图片的偏移量
@Prop tabBarIndex: number; // tabBar下标
@Link selectedIndex: number; // 初始化被选定的tabBar下标
build() {
Column() {
Stack() {
// 判断tab的下标是否不为1
if (this.tabBarIndex !== PUBLISH_TAB_BAR_INDEX) {
Column() {
// 通过被选中的tabBar下标值和tabBar的默认下标值来改变图片显示
Image(this.selectedIndex === this.tabBarIndex ? TABINFO[this.tabBarIndex].selectedIcon :
TABINFO[this.tabBarIndex].defaultIcon)
.width(28)
.height(28)
.interpolation(ImageInterpolation.High)
.offset({
y: (this.selectedIndex === this.tabBarIndex && this.selectedIndex !== PUBLISH_TAB_BAR_INDEX) ?
this.iconOffset : 0
})
.animation({
duration: 400,
curve: Curve.Ease,
iterations: 1,
playMode: PlayMode.Normal
})
}
.width(37)
.height(37)
.justifyContent(FlexAlign.Center)
} else {
Column() {
Image(this.selectedIndex === this.tabBarIndex ? TABINFO[this.tabBarIndex].selectedIcon :
TABINFO[this.tabBarIndex].defaultIcon)
.width(60)
.aspectRatio(1)
.margin({ top: 4 })
.interpolation(ImageInterpolation.High)
}
.width(80)
.height(80)
.borderRadius(40)
.margin({ top: -10 })
.backgroundColor($r('app.color.tab_bar_background'))
}
}
if (this.tabBarIndex !== PUBLISH_TAB_BAR_INDEX) {
Text(TABINFO[this.tabBarIndex].title)
.fontSize(14)
.fontColor(this.selectedIndex === this.tabBarIndex ? '#1296db' : '#707070')
}
}
.width(60)
.onClick(() => {
if (this.tabBarIndex === PUBLISH_TAB_BAR_INDEX) {
promptAction.showToast({
message: '这里随你所愿',
duration: 2000
});
} else {
this.iconOffset = -3;
this.selectedIndex = this.tabBarIndex;
}
})
}
}
更多推荐
所有评论(0)