鸿蒙Next - 导航条动态跟随效果制作

345 阅读2分钟

在大多数软件中都会有这种场景,作为一个初学者,第一眼看到没想出怎么做

写出一个还挺好理解的方法,遂发出来,欢迎大佬指正😣😣😣

GIF 9-7-2024 9-31-24 PM.gif

这里首先说一下这个通用方法, onAreaChange

image.png

为我们的标签加上这个方法

.onAreaChange((oldValue: Area, newValue: Area) => {
  console.log('wssb',JSON.stringify(newValue,null,2))
})

查看输出

image.png 有点乱,但一眼看到几个参数

image.png

很显然,这是三个标签组件的坐标

image.png

所以我们运用这个方法获得的坐标,来让一个公用的导航条动来动去🐣🐣

标签组件

@Builder
TopTab(title: string, index: number) {
  Row() {
    Text(title)
      .fontWeight(600)
      .lineHeight(22)
      .fontColor(this.SelectedIndex == index ? '#2A2929' : '#818181')
      .onClick(() => {
        this.SelectedIndex = index
      })
      .animation({curve:Curve.Ease,duration:300})
  }
  .justifyContent(FlexAlign.Center)
  .width(50)
  .onAreaChange((a,b) => {
    console.log('wssb',JSON.stringify(b))
    this.tabx[index] = Number(b.globalPosition.x)
  })
}

自制导航栏


tabx:number[] = [0,0,0]  //提前定义

Row({ space: 36 }) {
  this.TopTab('待提货', 0)
  this.TopTab('在途', 1)
  this.TopTab('已完成', 2)

  Text()
    .width(24)
    .height(3.5)
    .borderRadius(3)
    .linearGradient({
      direction: GradientDirection.Right,
      colors: [['#e62f23', 0.1], ['#f25c4d', 0.9]]
    })
    .position({x: this.tabx[this.SelectedIndex]-30, y: 28 }) 
    .animation({curve:Curve.Ease,duration:300})
}
.padding({ left: 30, top: 8, bottom: 20 })
.width('100%')
.backgroundColor('#fff')

实现思路是,在每个标签渲染时,将各自的坐标传入一个数组中,点击标签后,将导航条的x轴偏移值设置为数组中的指定值,配合动画属性,实现效果

GIF 9-7-2024 9-51-02 PM.gif

基本有效果了,这里运用简单的数学知识算一下,将导航条的坐标设置为标签左侧边界值 + 标签宽度的一半 - 导航条本身宽度的一半 就可以将导航条移动至标签正下方 也就是在存储坐标值时 加25(标签宽度50) 减去12(导航条宽度24)

  .onAreaChange((a,b) => {
    console.log('wssb',JSON.stringify(b))
    this.tabx[index] = Number(b.globalPosition.x) + 25 - 12
  })

获得我们需要的效果

GIF 9-7-2024 9-59-44 PM.gif

但是初始值需要自己写死,不够好😣😣

虽然我没试,但tabs组件的标签应该也可以用这个效果🚎

有大佬有更好的方法欢迎评论 (:зゝ∠)

9.13更新

经评论区大佬提醒,为TabBar使用SubTabBarStyle参数可以实现这个样式, 页签文字内容和导航条样式都可以调整,在开始滑动时导航条就会跟随

GIF 9-13-2024 10-11-43 PM.gif 示例: developer.huawei.com/consumer/cn…

虽然不能自定义样式,但大多数场景足够使用了 (‾◡◝)