HarmonyOS鸿蒙Next中如何实现页面上滑tabBar和顶部标题的悬停以及属性动画效果
HarmonyOS鸿蒙Next中如何实现页面上滑tabBar和顶部标题的悬停以及属性动画效果
【问题现象】
参照Scroll的示例3,实现了tabBar在页面顶部的悬停效果。
如果页面顶部还有一个标题栏(即下图中“首页”),现在要实现tab内容向上滚动时tabBar悬停到标题栏下方(即下图中“同城”,“推荐”,“活动”,“玩机”这一行),且可以实现标题栏在滚动过程中样式变化(如下图背景变化),该如何实现?
【背景知识】
- Scroll:可滚动容器,其中nestedScroll:设置父组件的滚动联动、onDidScroll:滚动事件回调
- Stack:堆叠容器
【解决方案】
-
使用Stack层叠布局,将标题栏悬浮展示在页面顶部。
-
考虑页面滚动以及tabContent里面的list滚动就要考虑滚动嵌套问题,目前场景需要选择:
- 向上滚动时,父组件先滚动,父组件滚动到边缘以后自身滚动;
- 向下滚动时:自身先滚动,自身滚动到边缘以后父组件滚动。
实现代码如下:
.nestedScroll({ scrollForward: NestedScrollMode.PARENT_FIRST, scrollBackward: NestedScrollMode.SELF_FIRST })
-
父组件滚动过程中,根据滚动偏移量线性修改标题栏样式(如字体大小、透明度、背景等),onDidScroll可以返回当前帧滚动的偏移量和当前滚动状态。
具体实现代码如下:
[@Entry](/user/Entry) [@Component](/user/Component) struct StickyNestedScroll { @State arr: number[] = [] @State opacityNum: number = 0 @State curYOffset: number = 0 aboutToAppear() { for (let i = 0; i < 30; i++) { this.arr.push(i) } } @Styles listCard() { .backgroundColor(Color.White) .height(72) .width('calc(100% - 20vp)') .borderRadius(12) .margin({ left: 10, right: 10 }) } build() { Stack() { Scroll() { Column() { Image($r('app.media.bg')) .width('100%') .height(300) Tabs({ barPosition: BarPosition.Start }) { TabContent() { List({ space: 10 }) { ForEach(this.arr, (item: number) => { ListItem() { Text("item" + item) .fontSize(20) }.listCard() }, (item: string) => item) }.width("100%") .edgeEffect(EdgeEffect.None) .nestedScroll({ scrollForward: NestedScrollMode.PARENT_FIRST, scrollBackward: NestedScrollMode.SELF_FIRST }) }.tabBar("待办") TabContent() { }.tabBar("待阅") } .vertical(false) .width("100%") .height('calc(100% - 60vp)') }.width("100%") } .friction(0.6) .backgroundColor('# DCDCDC') .scrollBar(BarState.Off) .width('100%') .height('100%') .onDidScroll((xOffset: number, yOffset: number, scrollState: ScrollState): void => { // 累计计算当前父组件滚动在Y轴方向的偏移量 this.curYOffset += yOffset // 根据父组件一共可以滚动的距离计算当前每帧的当前透明度 let opacity = this.curYOffset / 240 if (opacity >= 1) { opacity = 1 } if (opacity <= 0) { opacity = 0 } this.opacityNum = opacity }) // 悬浮标题栏 Text("工作台") .fontSize(24) .fontColor(Color.Black) .fontWeight(FontWeight.Bold) .backgroundColor(`rgba(255,255,255,${this.opacityNum})`) .position({ x: 0, y: 0 }) .width('100%') .height(60) .padding({ left: 20 }) }.width('100%') .height('100%') } }
效果如图:
【总结】
- 悬浮类布局首先考虑Stack层叠布局;
- 嵌套滚动,考虑父子组件之前的先后滚动模式,选择合适的滚动模式;
- 滚动过程中,获取当前滚动每帧偏移量和滚动状态,做合适的UI更新。
更多关于HarmonyOS鸿蒙Next中如何实现页面上滑tabBar和顶部标题的悬停以及属性动画效果的实战教程也可以访问 https://www.itying.com/category-93-b0.html
更多关于HarmonyOS鸿蒙Next中如何实现页面上滑tabBar和顶部标题的悬停以及属性动画效果的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html
使用Stack层叠布局将标题栏悬浮在页面顶部
通过nestedScroll
设置父组件和子组件的滚动模式,父组件先滚动,子组件后滚动。在onDidScroll
回调中获取滚动偏移量,动态调整标题栏的样式,如背景透明度。具体代码见帖子内容。