新增的onAnimationStart、onAnimationEnd和onGestureSwipe事件,本地测试不会感知到明显的延迟,demo如下:import ComponentUtils from '@ohos.arkui.UIContext'; @Entry @Component export default struct Index { message: string = '通讯录' @State selectedFontColor: string = '#007DFF' @State fontColor: string = '#182431' @State currentPosition: number = 0 // @Prop @Watch ('onRefresh') currentIndex: number private tabsController: TabsController = new TabsController() @State animationDuration: number = 300 @State indicatorLeftMargin: number = 0 @State indicatorWidth: number = 0 @State currentIndex: number = 0 private tabsWidth: number = 0 private componentUtils: ComponentUtils.ComponentUtils = this.getUIContext().getComponentUtils() @Builder TabBuilder(index: number, name: ESObject) { Column() { Row() { Text(name) .fontColor(this.currentPosition === index ? this.selectedFontColor : this.fontColor) .fontSize(16) .fontWeight(this.currentPosition === index ? 600 : 400) .lineHeight(22) .margin({ top: 5, bottom: 5, left: 2 }) }.width('95%').backgroundColor(this.currentPosition === index ? '#ffffff' : null).borderRadius(15) }.height('50%') } build() { Column() { Column() { Tabs({ barPosition: BarPosition.Start, index: this.currentPosition, controller: this.tabsController }) { TabContent() { Text('1111').fontSize(14) }.tabBar(this.TabBuilder(0, '最近联系人')) TabContent() { Text('2222').fontSize(14) }.tabBar(this.TabBuilder(1, '关注联系人')) TabContent() { Text('3333').fontSize(14) }.tabBar(this.TabBuilder(2, '我的群组')) } .vertical(false) .barMode(BarMode.Fixed) // .barWidth(360) .barHeight(65) .padding({ bottom: 15 }) .onChange((index: number) => { this.currentPosition = index }) .width('100%') .animationDuration(this.animationDuration) .onAnimationStart((index: number, targetIndex: number, event: TabsAnimationEvent) => { // 切换动画开始时触发该回调。下划线跟着页面一起滑动,同时宽度渐变。 this.currentPosition = targetIndex let targetIndexInfo = this.getTextInfo(targetIndex) this.startAnimateTo(this.animationDuration, targetIndexInfo.left, targetIndexInfo.width) }) .onAnimationEnd((index: number, event: TabsAnimationEvent) => { // 切换动画结束时触发该回调。下划线动画停止。 let currentIndicatorInfo = this.getCurrentIndicatorInfo(index, event) this.startAnimateTo(0, currentIndicatorInfo.left, currentIndicatorInfo.width) }) .onGestureSwipe((index: number, event: TabsAnimationEvent) => { // 在页面跟手滑动过程中,逐帧触发该回调。 let currentIndicatorInfo = this.getCurrentIndicatorInfo(index, event) this.currentIndex = currentIndicatorInfo.index this.indicatorLeftMargin = currentIndicatorInfo.left this.indicatorWidth = currentIndicatorInfo.width }) } .width('100%') .height('100%') .align(Alignment.TopStart) // .padding({top:20}) }.width('100%').height('100%') .backgroundImageSize(ImageSize.Cover) } private getTextInfo(index: number): Record<string, number> { let rectangle = this.componentUtils.getRectangleById(index.toString()) return { 'left': px2vp(rectangle.windowOffset.x), 'width': px2vp(rectangle.size.width) } } private getCurrentIndicatorInfo(index: number, event: TabsAnimationEvent): Record<string, number> { let nextIndex = index if (index > 0 && event.currentOffset > 0) { nextIndex-- } else if (index < 3 && event.currentOffset < 0) { nextIndex++ } let indexInfo = this.getTextInfo(index) let nextIndexInfo = this.getTextInfo(nextIndex) let swipeRatio = Math.abs(event.currentOffset / this.tabsWidth) let currentIndex = swipeRatio > 0.5 ? nextIndex : index // 页面滑动超过一半,tabBar切换到下一页。 let currentLeft = indexInfo.left + (nextIndexInfo.left - indexInfo.left) * swipeRatio let currentWidth = indexInfo.width + (nextIndexInfo.width - indexInfo.width) * swipeRatio return { 'index': currentIndex, 'left': currentLeft, 'width': currentWidth } } private startAnimateTo(duration: number, leftMargin: number, width: number) { animateTo({ duration: duration, // 动画时长 curve: Curve.Linear, // 动画曲线 iterations: 1, // 播放次数 playMode: PlayMode.Normal, // 动画模式 onFinish: () => { console.info('play end') } }, () => { this.indicatorLeftMargin = leftMargin this.indicatorWidth = width }) } }文档链接:https://developer.huawei.com/consumer/cn/doc/harmonyos-references-V5/ts-container-tabs-V5\#事件
新增的onAnimationStart、onAnimationEnd和onGestureSwipe事件,本地测试不会感知到明显的延迟,demo如下:
文档链接:https://developer.huawei.com/consumer/cn/doc/harmonyos-references-V5/ts-container-tabs-V5\#事件