HarmonyOS鸿蒙Next中如何解决Tab组件嵌套使用时滑动事件冲突
HarmonyOS鸿蒙Next中如何解决Tab组件嵌套使用时滑动事件冲突
【问题现象】
在一个Tab组件下嵌套使用了二级Tab,当二级Tab第一个页面左滑或最后一个页面右滑不能切换到一级Tab标签的前一个Tab或后一个Tab。
【背景知识】
- 拖动手势(PanGesture):拖动手势用于触发拖动手势事件。
- Pangesture的API介绍:拖动手势事件,当滑动的最小距离达到设定的最小值时触发拖动手势事件。
- TabsController控制器:Tabs组件的控制器,用于控制Tabs组件进行页签切换。
【定位思路】
单独使用Tab组件可以直接触发滑动手势。但是,当Tab组件内嵌套了一个子Tab后,由于在子Tab上触发的滑动手势只能作用于当前的组件也就是子Tab上。从而导致手势触发无法作用到父组件的Tab上。
【解决方案】
把子Tab组件再嵌套在一个Column组件内,通过Column组件绑定手势触发。当Column内的Tab触发了首页右滑,或者尾页左滑时。使用TabsController控制器,来改变父Tab的标签index,从而达到控制子Tab首页右滑,或者尾页左滑时,一级Tab左右滑动的效果。
在二级Tab绑定拖动手势事件的方式,当事件触发时,用一级Tabs组件的控制器TabsController切换到一级Tabs指定页签。效果如下:
代码示例如下:
Column() {
//一级Tabs,并指定Tabs控制器
Tabs({ barPosition: BarPosition.Start, index: this.currentIndex, controller: this.controller }) {
TabContent() {
Column().width('100%').height('100%').backgroundColor('#ffb554d7')
}.tabBar(this.tabBuilder(0, '首页'))
TabContent() {
Column(){
//二级Tabs
Tabs({ barPosition: BarPosition.Start,controller: this.subController }) {
TabContent() {
Column().width('100%').height('100%').backgroundColor('#00CB87')
//绑定拖动手势
.gesture(
// 二级Tabs第一个页签向左拖动时,触发手势事件
PanGesture(this.panOptionLeft)
.onActionStart((event?: GestureEvent) => {
console.info('Pan start')
})
// 通过父组件的TabsController的实例,改变其index,达到跳转一级Tabs(首页)的效果
.onActionEnd(() => {
this.controller.changeIndex(0)
console.info('Pan end')
})
)
}.tabBar(this.subTabBuilder(0, 'green'))
TabContent() {
Column().width('100%').height('100%').backgroundColor('#007DFF')
}.tabBar(this.subTabBuilder(1, 'blue'))
TabContent() {
Column().width('100%').height('100%').backgroundColor('#FFBF00')
}.tabBar(this.subTabBuilder(2, 'yellow'))
TabContent() {
Column().width('100%').height('100%').backgroundColor('#E67C92')
.gesture(
// 二级Tabs最后一个页签向右拖动时,触发手势事件
PanGesture(this.panOptionRight)
.onActionStart((event?: GestureEvent) => {
console.info('Pan start')
})
// 通过父组件的TabsController的实例,改变其index,达到跳转一级Tabs(首页)的效果
.onActionEnd(() => {
this.controller.changeIndex(2)
console.info('Pan end')
})
)
}.tabBar(this.subTabBuilder(3, 'pink'))
}
.vertical(false)
.barMode(BarMode.Fixed)
.barWidth(360)
.barHeight(56)
.animationDuration(400)
.onChange((index: number) => {
this.subCurrentIndex = index
})
.width(360)
.backgroundColor('#F1F3F5')
}
.width('100%').height('100%').backgroundColor('#00CB87')
}.tabBar(this.tabBuilder(1, '详情'))
TabContent() {
Column().width('100%').height('100%').backgroundColor('#ffc19757')
}.tabBar(this.tabBuilder(2, '我的'))
}
.vertical(false)
.barMode(BarMode.Fixed)
.barWidth(360)
.barHeight(56)
.animationDuration(400)
.onChange((index: number) => {
this.currentIndex = index
})
.width(360)
.height(296)
.margin({ top: 52 })
.backgroundColor('#F1F3F5')
}.width('100%')
【总结】
ArkUI为开发提供了完整的基础设施和丰富的能力,灵活的运用各种组件的能力,可以让开发者实现预期的效果。从而为最终使用者提供丰富、良好的交互体验。
更多关于HarmonyOS鸿蒙Next中如何解决Tab组件嵌套使用时滑动事件冲突的实战教程也可以访问 https://www.itying.com/category-93-b0.html
更多关于HarmonyOS鸿蒙Next中如何解决Tab组件嵌套使用时滑动事件冲突的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html
将子Tab组件嵌套在Column组件内
通过Column组件绑定手势触发。当二级Tab的第一个页面左滑或最后一个页面右滑时,使用TabsController控制器改变一级Tab的标签index,实现一级Tab的左右滑动效果。具体代码示例如下:
Column() {
Tabs({ barPosition: BarPosition.Start, index: this.currentIndex, controller: this.controller }) {
TabContent() {
Column().width('100%').height('100%').backgroundColor('#ffb554d7')
}.tabBar(this.tabBuilder(0, '首页'))
TabContent() {
Column() {
Tabs({ barPosition: BarPosition.Start, controller: this.subController }) {
TabContent() {
Column().width('100%').height('100%').backgroundColor('#00CB87')
.gesture(
PanGesture(this.panOptionLeft)
.onActionStart((event?: GestureEvent) => {
console.info('Pan start')
})
.onActionEnd(() => {
this.controller.changeIndex(0)
console.info('Pan end')
})
)
}.tabBar(this.subTabBuilder(0, 'green'))
TabContent() {
Column().width('100%').height('100%').backgroundColor('#007DFF')
}.tabBar(this.subTabBuilder(1, 'blue'))
TabContent() {
Column().width('100%').height('100%').backgroundColor('#FFBF00')
}.tabBar(this.subTabBuilder(2, 'yellow'))
TabContent() {
Column().width('100%').height('100%').backgroundColor('#E67C92')
.gesture(
PanGesture(this.panOptionRight)
.onActionStart((event?: GestureEvent) => {
console.info('Pan start')
})
.onActionEnd(() => {
this.controller.changeIndex(2)
console.info('Pan end')
})
)
}.tabBar(this.subTabBuilder(3, 'pink'))
}
.vertical(false)
.barMode(BarMode.Fixed)
.barWidth(360)
.barHeight(56)
.animationDuration(400)
.onChange((index: number) => {
this.subCurrentIndex = index
})
.width(360)
.backgroundColor('#F1F3F5')
}
.width('100%').height('100%').backgroundColor('#00CB87')
}.tabBar(this.tabBuilder(1, '详情'))
TabContent() {
Column().width('100%').height('100%').backgroundColor('#ffc19757')
}.tabBar(this.tabBuilder(2, '我的'))
}
.vertical(false)
.barMode(BarMode.Fixed)
.barWidth(360)
.barHeight(56)
.animationDuration(400)
.onChange((index: number) => {
this.currentIndex = index
})
.width(360)
.height(296)
.margin({ top: 52 })
.backgroundColor('#F1F3F5')
}.width('100%')