HarmonyOS鸿蒙Next中scroll嵌套Tabs自动吸顶了怎么去除

HarmonyOS鸿蒙Next中scroll嵌套Tabs自动吸顶了怎么去除 cke_767.gif

这里一旦滑动他就会吸附在顶部

整体代码

Scroll(){

  Column() {

    Blank().width('100%').height(px2vp(AppUtil.getStatusBarHeight()))

    Stack({ alignContent: Alignment.BottomEnd }) {

      Swiper() {
        ForEach(this.mSwiperImages, (item: Resource) => {
          Image(item)
            .width('100%')
            .height(242)
            .objectFit(ImageFit.Fill)
        })
      }
      .onChange((data) => {
        this.selectSwiperIndex = data
      })
      .index(this.selectSwiperIndex)
      .width('100%')
      .constraintSize({ maxWidth: '100%' })
      // .margin({ left: 15, right: 15 })
      .indicator(false) //选中颜色
      .autoPlay(true)
      .interval(1500)

      Row({ space: 8 }) {

        ForEach(this.mSwiperImages, (item: string, index: number) => {
          Circle()
            .width(6)
            .height(6)
            .fill(this.selectSwiperIndex == index ? Color.White : Color.Transparent)
            .stroke('#fff')
        }, (item: string) => item)

      }.margin({ bottom: 20, right: 32 })
      .alignRules({
        bottom: { anchor: '__container__', align: VerticalAlign.Bottom },
        right: { anchor: '__container__', align: HorizontalAlign.End },
      })

    }

    Column() {

      Tabs({ barPosition: BarPosition.Start, index: this.mTabSelectIndex }) {

        ForEach(this.mAllDatas, (item: BottomDatas[], index: number) => {

          TabContent() {

              WaterFlow() {
                ForEach(this.mAllDatas[index].datas, (item: DataTabIndex, index: number) => {
                  FlowItem() {
                    Column() {
                      Image(item.resourcePreviewUrl).borderRadius({
                        topLeft: 12,
                        topRight: 12
                      }).width('100%').alt($r('app.media.loding'))

                      Text(item.title)
                        .width('100%')
                        .height(40)
                        .backgroundColor('#F6F6F6')
                        .fontSize(15)
                        .fontColor('#0B2936')
                        .padding(12)
                        .borderRadius({ bottomLeft: 12, bottomRight: 12 })
                    }.onClick(() => {
                      console.log(item.description)
                      let obj = {
                        "type": item.description == '宠物相机' ? '宠物写真' : item.description,
                      } as Record<string, string | number | boolean>
                      this.pathInfos.pushPathByName('details', obj)
                    })
                  }.width('100%')
                })
              }
              .edgeEffect(EdgeEffect.Spring)
              .nestedScroll({
                scrollForward: NestedScrollMode.PARENT_FIRST,
                scrollBackward: NestedScrollMode.SELF_FIRST
              })

              .columnsTemplate('1fr 1fr')
              .columnsGap(10)
              .rowsGap(10)
              .width('100%')
              .height('100%')
              .constraintSize({ maxWidth: '100%' })
              .margin({ top: 6, left: 16, right: 16 })
              // .layoutWeight(1)

          }.tabBar(SubTabBarStyle.of(this.mAllDatas[index].title)
            .labelStyle({
              font: { weight: this.mTabSelectIndex === index ? 700 : 400 },
              selectedColor: '#3D3D3D',
              unselectedColor: '#3D3D3D'
            })
            .indicator({
              color: '#FFE5CC',
              width: 0,
              height: 2,
              borderRadius: 0,
              marginTop: 4
            }))

        })
      }
      .scrollable(true)
      .barMode(BarMode.Fixed)
      .width('100%')
      .layoutWeight(1)
      .vertical(false)
      .edgeEffect(EdgeEffect.None)
      .animationDuration(300)
      .onAnimationStart((index: number, targetIndex: number, extraInfo: TabsAnimationEvent) => {
        this.mTabSelectIndex = targetIndex
        this.isShowBar = true
      })
      .onGestureRecognizerJudgeBegin((event: BaseGestureEvent, current: GestureRecognizer,
        _: Array<GestureRecognizer>): GestureJudgeResult => { // 在识别器即将要成功时,根据当前组件状态,设置识别器使能状态

        if (current) {
          let target = current.getEventTargetInfo();
          if (target && current.isBuiltIn() && current.getType() == GestureControl.GestureType.PAN_GESTURE) {
            let panEvent = event as PanGestureEvent;
            if (panEvent && panEvent.velocityX < 0 &&
              this.mTabSelectIndex === this.mAllDatas.length - 1) { // 内层Tabs滑动到尽头
              return GestureJudgeResult.REJECT;
            }
            if (panEvent && panEvent.velocityX > 0 && this.mTabSelectIndex === 0) { // 内层Tabs滑动到开头
              return GestureJudgeResult.REJECT;
            }
          }
        }
        return GestureJudgeResult.CONTINUE;
      }, true)

    }.width('100%').height('100%')

  }.width('100%')

}.width('100%').height('100%').edgeEffect(EdgeEffect.None).scrollBar(BarState.Off)
.scrollable(ScrollDirection.Vertical) .align(Alignment.Top)

更多关于HarmonyOS鸿蒙Next中scroll嵌套Tabs自动吸顶了怎么去除的实战教程也可以访问 https://www.itying.com/category-93-b0.html

5 回复

【解决方案】

开发者您好,出现吸顶效果的原因与下列代码有关:

.nestedScroll({
  scrollForward: NestedScrollMode.PARENT_FIRST, // 向上滚动PARENT_FIRST:父组件先滚动,父组件滚动到边缘以后自身滚动。
  scrollBackward: NestedScrollMode.SELF_FIRST // 向下滚动SELF_FIRST:自身先滚动,自身滚动到边缘以后父组件滚动。
})

如果想要取消吸顶效果,可以将代码进行如下修改:

// 移除 nestedScroll 属性,或设置为 SELF_FIRST 模式
.nestedScroll({
  scrollForward: NestedScrollMode.SELF_FIRST,  // 优先自身滚动
  scrollBackward: NestedScrollMode.SELF_FIRST
})

【背景知识】

吸顶效果是网页开发中的一种常见交互设计,指当用户滚动页面时,某个元素(如导航栏、标题栏、工具栏等)会固定在浏览器窗口的顶部(或其他指定位置),保持始终可见,不会随着页面滚动而消失。在开发过程中,吸顶效果通常用于需要保持关键元素始终可见的场景,以提升用户体验和操作效率。

在HarmonyOS中有多种实现吸顶效果的方案,以及不同的吸顶效果,不同方案及需要了解的知识如下:

  • Tabs:通过页签进行内容视图切换的容器组件,每个页签对应一个内容视图。
  • nestedScroll属性:设置前后两个方向的嵌套滚动模式,实现与父组件的滚动联动。

更多关于HarmonyOS鸿蒙Next中scroll嵌套Tabs自动吸顶了怎么去除的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html


大佬 这样的话 还可以实现整体滑动的效果吗~,

取消吸顶理论上不影响滚动效果,如果您遇到内容显示截断问题可以考虑将父容器固定高度调整为动态高度。

在HarmonyOS Next中,若Scroll嵌套Tabs出现自动吸顶,可通过修改Tabs组件的barOverlap属性为false来禁用吸顶效果。同时检查Scroll和Tabs的布局结构,确保未设置sticky等固定定位属性。若使用ArkUI声明式开发,调整Tabs的barPosition为非固定位置也可解决。具体属性设置需根据实际组件版本确认。

在HarmonyOS Next中,Tabs组件默认具有吸顶效果。要去除这个自动吸顶行为,需要修改Tabs的barMode属性。

将代码中的:

.barMode(BarMode.Fixed)

改为:

.barMode(BarMode.Scrollable)

这样修改后,Tabs的标签栏将不再固定在顶部,而是会随着Scroll组件的滚动而滚动。BarMode.Scrollable模式允许标签栏在内容滚动时正常滚动,而不是固定在视口顶部。

同时,由于你的Tabs嵌套在Scroll中,建议确保Tabs的父容器高度设置正确,避免布局冲突。当前代码中Tabs已经设置了.layoutWeight(1),这有助于正确分配剩余空间。

修改后的Tabs配置将不再自动吸顶,标签栏会与页面其他内容一起正常滚动。

回到顶部