HarmonyOS 鸿蒙Next悬停动画

HarmonyOS 鸿蒙Next悬停动画 如何实现页面上滑tabBar和顶部标题的悬停以及属性动画效果

3 回复

可以参考 如何实现页面上滑tabBar和顶部标题的悬停以及属性动画效果

  1. 使用Stack层叠布局,将标题栏悬浮展示在页面顶部。
  2. 考虑页面滚动以及tabContent里面的list滚动就要考虑滚动嵌套问题,目前场景需要选择:
    • 向上滚动时,父组件先滚动,父组件滚动到边缘以后自身滚。
    • 向下滚动时:自身先滚动,自身滚动到边缘以后父组件滚动。
    • .nestedScroll({
        scrollForward: NestedScrollMode.PARENT_FIRST,
        scrollBackward: NestedScrollMode.SELF_FIRST
      })
      
  3. 父组件滚动过程中,根据滚动偏移量线性修改标题栏样式(如字体大小、透明度、背景等),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.background'))// 图片资源需自行替换
                .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%')
      }
    }
    

更多关于HarmonyOS 鸿蒙Next悬停动画的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html


HarmonyOS Next的悬停动画基于ArkUI框架实现,通过state management管理组件状态变化。该动画使用属性动画和显式动画机制,响应组件hover状态的布尔值变化。在声明式语法中,可通过.hoverEffect()修饰符或onHover回调触发动画效果。系统预置了缩放、高亮等标准悬停动效,开发者也可通过自定义动画属性实现个性化交互效果。动画执行由系统统一管理,确保流畅性和性能优化。

在HarmonyOS Next中实现页面滑动时TabBar和标题栏的悬停动画效果,可以通过以下方式实现:

  1. 使用Scroll组件监听滚动位置

    • 通过Scroll组件的onScroll事件获取滚动偏移量
    • 根据滚动位置动态计算组件透明度、位移等属性
  2. 属性动画实现

    // 示例代码
    [@State](/user/State) scrollY: number = 0
    [@State](/user/State) tabBarOpacity: number = 1
    
    Scroll() {
      // 页面内容
    }
    .onScroll((xOffset: number, yOffset: number) => {
      this.scrollY = yOffset
      // 根据滚动位置计算透明度
      this.tabBarOpacity = Math.max(0, 1 - yOffset / 200)
    })
    
    // TabBar组件
    Column() {
      // TabBar内容
    }
    .opacity(this.tabBarOpacity)
    .translate({ y: -this.scrollY * 0.5 })
    .animation({ duration: 100, curve: Curve.Ease })
    
  3. 关键实现点

    • 使用@State装饰器管理动画状态
    • 通过translate实现位移动画
    • 设置合适的animation参数控制动画曲线和时长
    • 根据实际需求调整悬停阈值和动画效果

这种方法可以实现流畅的悬停动画效果,同时保持较好的性能表现。

回到顶部