Toggle navigation
Toggle navigation
This project
Loading...
Sign in
developOne
/
harmonyPool
Go to a project
Toggle navigation
Projects
Groups
Snippets
Help
Toggle navigation pinning
Project
Activity
Repository
Pipelines
Graphs
Issues
0
Merge Requests
0
Wiki
Network
Create a new issue
Builds
Commits
Authored by
张善主
2024-04-28 13:48:14 +0800
Browse Files
Options
Browse Files
Download
Email Patches
Plain Diff
Commit
0d9d3327add8908c965d924c4d6e4ef78b490fbd
0d9d3327
1 parent
18412761
feat(tab):顶部tab切换同步
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
97 additions
and
1 deletions
sight_harmony/features/wdComponent/src/main/ets/components/page/TopNavigationComponent.ets
sight_harmony/features/wdComponent/src/main/ets/components/page/TopNavigationComponent.ets
View file @
0d9d332
...
...
@@ -58,6 +58,11 @@ export struct TopNavigationComponent {
// 当前底导index
@State navIndex: number = 0
@State animationDuration: number = 0
@State indicatorLeftMargin: number = 0
@State indicatorWidth: number = 0
private tabsWidth: number = 0
topOrBottomNavChange() {
if (this.currentBottomNavName === this.currentBottomNavInfo?.name) {
this.setBarBackgroundColor()
...
...
@@ -162,6 +167,7 @@ export struct TopNavigationComponent {
return item.name === '版面'
}
build() {
Column() {
// 顶部搜索、日报logo、早晚报
...
...
@@ -237,9 +243,13 @@ export struct TopNavigationComponent {
.barMode(BarMode.Scrollable)
.vertical(false)
.barBackgroundColor(this.barBackgroundColor)
.onAreaChange((oldValue: Area,newValue: Area)=> {
let width = Number.parseFloat(newValue.width.toString())
this.tabsWidth = Number.isNaN(width) ? 0 : width
})
.animationDuration(this.animationDuration)
.onChange((index: number) => {
this.currentTopNavName = this._currentNavIndex === 0 ? this.myChannelList[index].name : this.topNavList[index].name
Logger.info(TAG, `onChange index : ${index}`);
if (!this.isBroadcast(this._currentNavIndex === 0 ? this.myChannelList[index] : this.topNavList[index]) &&
!this.isLayout(this._currentNavIndex === 0 ? this.myChannelList[index] : this.topNavList[index])
...
...
@@ -256,6 +266,39 @@ export struct TopNavigationComponent {
this.tabsController.changeIndex(this.currentTopNavSelectedIndex)
}
})
.onAnimationStart((index: number, targetIndex: number, event: TabsAnimationEvent) => {
if (!this.isBroadcast(this._currentNavIndex === 0 ? this.myChannelList[index] : this.topNavList[index]) &&
!this.isLayout(this._currentNavIndex === 0 ? this.myChannelList[index] : this.topNavList[index])
) {
return
}
this.currentTopNavSelectedIndex = targetIndex
// 切换动画开始时触发该回调。下划线跟着页面一起滑动,同时宽度渐变。
let targetIndexInfo = this.getTextInfo(targetIndex)
this.startAnimateTo(this.animationDuration, targetIndexInfo.left, targetIndexInfo.width)
})
.onAnimationEnd((index: number,event: TabsAnimationEvent) => {
if (!this.isBroadcast(this._currentNavIndex === 0 ? this.myChannelList[index] : this.topNavList[index]) &&
!this.isLayout(this._currentNavIndex === 0 ? this.myChannelList[index] : this.topNavList[index])
) {
return
}
// 切换动画结束时触发该回调。下划线动画停止。
let currentIndicatorInfo = this.getCurrentIndicatorInfo(index,event)
this.startAnimateTo(0,currentIndicatorInfo.left,currentIndicatorInfo.width)
})
.onGestureSwipe((index: number,event: TabsAnimationEvent) => {
if (!this.isBroadcast(this._currentNavIndex === 0 ? this.myChannelList[index] : this.topNavList[index]) &&
!this.isLayout(this._currentNavIndex === 0 ? this.myChannelList[index] : this.topNavList[index])
) {
return
}
// 在页面跟手滑动过程中,逐帧触发该回调。
let currentIndicatorInfo = this.getCurrentIndicatorInfo(index,event)
this.currentTopNavSelectedIndex = currentIndicatorInfo.index
this.indicatorLeftMargin = currentIndicatorInfo.left
this.indicatorWidth = currentIndicatorInfo.width
})
// 分类列表最右侧频道设置
if (this._currentNavIndex === 0) {
...
...
@@ -296,6 +339,17 @@ export struct TopNavigationComponent {
.fontColor(this.getTopNavFontColor(item, index))
.padding({ top: $r('app.float.top_tab_item_padding_top'), bottom: $r('app.float.top_tab_item_padding_bottom') })
.maxLines(this.MAX_LINE)
.id(index.toString())
.onAreaChange((oldValue: Area,newValue: Area) => {
if (this.currentTopNavSelectedIndex === index && (this.indicatorLeftMargin === 0 || this.indicatorWidth === 0)){
if (newValue.position.x != undefined) {
let positionX = Number.parseFloat(newValue.position.x.toString())
this.indicatorLeftMargin = Number.isNaN(positionX) ? 0 : positionX
}
let width = Number.parseFloat(newValue.width.toString())
this.indicatorWidth = Number.isNaN(width) ? 0 : width
}
})
// .backgroundImage(this.currentTopNavSelectedIndex === index ? item.iconCUrl : item.iconUrl)
if (this.currentTopNavSelectedIndex === index) {
Row()
...
...
@@ -418,4 +472,46 @@ export struct TopNavigationComponent {
}
return null
}
private getTextInfo(index: number): Record<string, number> {
let strJson = getInspectorByKey(index.toString())
try {
let obj: Record<string, string> = JSON.parse(strJson)
let rectInfo: number[][] = JSON.parse('[' + obj.$rect + ']')
return { 'left': px2vp(rectInfo[0][0]), 'width': px2vp(rectInfo[1][0] - rectInfo[0][0]) }
} catch (error) {
return { 'left': 0, 'width': 0 }
}
}
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
})
}
}
\ No newline at end of file
...
...
Please
register
or
login
to post a comment