HarmonyOS鸿蒙Next中Tabs组件实现的侧边栏,如何实现自顶到底的效果
HarmonyOS鸿蒙Next中Tabs组件实现的侧边栏,如何实现自顶到底的效果
【问题现象】
在实现侧边栏时,希望侧边栏从最顶部开始往下排列,在条目撑满侧边栏时可以滑动,且在选中条目时能自动居中。但是使用Tabs组件中把页签设置在侧边,页签中的条目始终是居中排列,无法做到从最顶部开始往下排列,如下图:
【背景知识】
- Tabs组件的使用:是一种常见的界面导航结构。通过页签容器,用户可以快捷地访问应用的不同模块。
- 使用Tabs组件时,可以使用barMode(BarMode.Scrollable)配置实现可滚动页签,但是Tabs组件中条目高度无法自定义,而且条目数量未撑满Tabs组件时,无法实现自顶到底的效果。
【解决方案】
由于原生Tabs组件无法实现自顶到底的效果,所以只能实现自定义组件来达到此效果。本篇采取Column + Scroll实现自定义TabBar组件,如下:
(1)用Column组件实现侧边栏,通过设置justifyContent(FlexAlign.Start)来实现侧边栏条目从顶部开始;
(2)用Scroll组件实现选中侧边栏条目时居中效果;
- 侧边栏从顶部开始。
代码示例如下:
Column({
Text("tab0")
.tabBarStyle(this.currentIndex == 0)
.onClick(() => {
this.currentIndex = 0
})
Text("tab1")
.tabBarStyle(this.currentIndex == 1)
.onClick(() => {
this.currentIndex = 1
})
}
.justifyContent(FlexAlign.Start) // 设置自顶向下
- 页面超过一半时TabBar组件内条目切换到下一页。
代码示例如下:
// 滑动页面超过一半时页面切换
this.swipeRatio = Math.abs(event.currentOffset / this.tabsWidth);
let currentIndex = this.swipeRatio > 0.5 ? nextIndex : index; // 页面滑动超过一半,TabBar组件切换到下一页。
let currentLeft = indexInfo.left + (nextIndexInfo.left - indexInfo.left) * this.swipeRatio;
let currentWidth = indexInfo.width + (nextIndexInfo.width - indexInfo.width) * this.swipeRatio;
this.indicatorIndex = currentIndex;
return { 'index': currentIndex, 'left': currentLeft, 'width': currentWidth };
- TabBar组件内条目可滑动时,将其定位在正中间。
代码示例如下:
this.scroller.scrollTo({
// 选中后定位在正中间
xOffset: 0,
yOffset: currentOffsetY + tabPositionTop - screenHeight / 2 + tabHeight / 2,
animation: {
duration: this.animationDuration,
curve: this.animationCurve, // 设置动画曲线
}
});
实现效果:
更多关于HarmonyOS鸿蒙Next中Tabs组件实现的侧边栏,如何实现自顶到底的效果的实战教程也可以访问 https://www.itying.com/category-93-b0.html
1 回复
更多关于HarmonyOS鸿蒙Next中Tabs组件实现的侧边栏,如何实现自顶到底的效果的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html
使用Column + Scroll实现自定义TabBar组件
通过设置justifyContent(FlexAlign.Start)
使侧边栏条目从顶部开始排列。Scroll
组件用于实现选中条目时自动居中效果。代码示例如下:
Column({
Text("tab0")
.tabBarStyle(this.currentIndex == 0)
.onClick(() => {
this.currentIndex = 0
})
Text("tab1")
.tabBarStyle(this.currentIndex == 1)
.onClick(() => {
this.currentIndex = 1
})
}
.justifyContent(FlexAlign.Start) // 设置自顶向下
滑动页面超过一半时,TabBar组件内条目切换到下一页:
// 滑动页面超过一半时页面切换
this.swipeRatio = Math.abs(event.currentOffset / this.tabsWidth);
let currentIndex = this.swipeRatio > 0.5 ? nextIndex : index; // 页面滑动超过一半,TabBar组件切换到下一页。
let currentLeft = indexInfo.left + (nextIndexInfo.left - indexInfo.left) * this.swipeRatio;
let currentWidth = indexInfo.width + (nextIndexInfo.width - indexInfo.width) * this.swipeRatio;
this.indicatorIndex = currentIndex;
return { 'index': currentIndex, 'left': currentLeft, 'width': currentWidth };
TabBar组件内条目可滑动时,将其定位在正中间:
this.scroller.scrollTo({
// 选中后定位在正中间
xOffset: 0,
yOffset: currentOffsetY + tabPositionTop - screenHeight / 2 + tabHeight / 2,
animation: {
duration: this.animationDuration,
curve: this.animationCurve, // 设置动画曲线
}
});