HarmonyOS鸿蒙Next中scroll嵌套list如何实现只滑动整个scroll

HarmonyOS鸿蒙Next中scroll嵌套list如何实现只滑动整个scroll scroll 嵌套 list如何实现 只滑动整个scroll

10 回复

**省流:**在List组件上设置 enableScrollInteraction(false)

实现方法

要实现Scroll嵌套List时只滑动整个Scroll(即List组件不单独响应滚动手势,所有滚动操作由Scroll组件处理),您可以通过设置List组件的enableScrollInteraction属性为false来实现。这样,List组件将无法通过手指或鼠标滚动手势滚动,但滚动事件会传递给父Scroll组件,从而只滑动整个Scroll。

具体步骤

  1. 在List组件上设置enableScrollInteraction(false):这将禁用List组件的滚动手势,确保用户操作时只有Scroll组件滚动。
  2. 确保Scroll组件可滚动:Scroll组件默认支持滚动,无需额外设置。

代码示例

@Entry
@Component
struct ScrollWithList {
  private arr: number[] = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]; // 示例数据

  build() {
    Scroll() {
      List() {
        ForEach(this.arr, (item: number) => {
          ListItem() {
            Text(`Item ${item}`)
              .width('100%')
              .height(100)
              .fontSize(16)
              .textAlign(TextAlign.Center)
              .backgroundColor(0xFFFFFF)
          }
        }, (item: number) => item.toString())
      }
      .enableScrollInteraction(false) // 关键设置:禁用List的滚动手势
      .width('100%')
      .height('100%') // 建议设置List的固定高度,以避免性能问题
    }
    .width('100%')
    .height('100%')
  }
}

说明

  • enableScrollInteraction属性:设置为false后,List组件无法通过手指或鼠标滚动手势滚动,但仍可通过Scroller控制器以编程方式滚动(不影响控制器接口)。
  • 嵌套滚动行为:此设置确保了滚动事件由父Scroll组件处理,实现了"只滑动整个Scroll"的效果。

注意事项

  • 此方法仅禁用滚动手势,List组件的内容仍然可以通过Scroller控制器以编程方式滚动(如调用scrollTo方法)。
  • 如果希望完全禁止List组件的所有滚动(包括编程方式),可能需要其他逻辑控制,但不建议这样做。

更多关于HarmonyOS鸿蒙Next中scroll嵌套list如何实现只滑动整个scroll的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html


目前按照这个方法写了,可能是我的场景有问题,tab->tabContent->Scroll->column-> 头部+list 这样设置了之后,只可以滚动一个一部分距离,就不能再滑下去了,

我想给List 添加 .layoutWeight(1) 加上之后 一部分距离也不能滑动了。完整的无法滑动。

背景知识:

楼主需要使用scroll 嵌套 list只滑动整个scroll。直接在scroll。里面嵌套一个list,不要设置高度。

问题处理:

示例代码:

@Entry
@Component
struct ScollPage {
    @State message: string = 'Hello World';
    @State list: Array<string> = []

    aboutToAppear(): void {
        //生成20个数据
        for (let i = 0; i < 20; i++) {
            this.list.push("测试数据" + i)
        }
    }

    build() {
        Column() {
            Scroll() {
                Column() {
                    //创建三个控件 text list text ;text的高度为100vp
                    Text("第一块")
                        .width("100%")
                        .height("100vp")
                        .textAlign(TextAlign.Center)
                        .backgroundColor(Color.Pink)
                    List({ space: 10 }) {
                        ForEach(this.list, (item: string) => {
                            ListItem() {
                                Text(item)
                                    .height('50vp')
                                    .width("100%")
                                    .backgroundColor('#fff')
                                    .fontSize(16)
                                    .textAlign(TextAlign.Center)
                            }
                        })
                    }.width("100%")
                    //将其放开后可以得到只滑动list部分。 见图2
                    //.layoutWeight(1)

                    Text("第二块")
                        .width("100%")
                        .height("100vp")
                        .textAlign(TextAlign.Center)
                        .backgroundColor(Color.Pink)
                }
                .width("100%")
            }
            .width("100%")
        }
        .height('100%')
        .width('100%')
    }
}

真机演示
图1

cke_23742.gif

图2

cke_21682.png

1.知识背景

嵌套滚动是指多个滚动容器相互嵌套,并能协同工作的滚动机制。例如:在移动端应用中,一个页面整体可以垂直滚动,而其中某个子组件(如Tab内容、评论区、图片列表)也只支持独立滚动。根据滚动对象的不同,嵌套滚动主要分为Scroll组件嵌套List组件、Web组件嵌套List组件、List组件嵌套List组件等。

2.解决方案

可以使用onScrollFrameBegin事件实现了内层List组件和外层Scroll组件的嵌套滚动。

代码示例:

import { LengthMetrics } from '@kit.ArkUI';

@Entry
@Component
struct NestedScroll {
  @State listPosition: number = 0; // 0代表滚动到List顶部,1代表中间值,2代表滚动到List底部。
  private arr: number[] = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
  private scrollerForScroll: Scroller = new Scroller();
  private scrollerForList: Scroller = new Scroller();

  build() {
    Flex() {
      Scroll(this.scrollerForScroll) {
        Column() {
          Text("Scroll Area")
            .width("100%")
            .height("40%")
            .backgroundColor(0X330000FF)
            .fontSize(16)
            .textAlign(TextAlign.Center)
            .onClick(() => {
              this.scrollerForList.scrollToIndex(5, false, ScrollAlign.START, { extraOffset: LengthMetrics.vp(5) });
            })

          List({ space: 20, scroller: this.scrollerForList }) {
            ForEach(this.arr, (item: number) => {
              ListItem() {
                Text("ListItem" + item)
                  .width("100%")
                  .height("100%")
                  .borderRadius(15)
                  .fontSize(16)
                  .textAlign(TextAlign.Center)
                  .backgroundColor(Color.White)
              }.width("100%").height(100)
            }, (item: string) => item)
          }
          .width("100%")
          .height("50%")
          .edgeEffect(EdgeEffect.None)
          .friction(0.6)
          .onReachStart(() => {
            this.listPosition = 0;
          })
          .onReachEnd(() => {
            this.listPosition = 2;
          })
          .onScrollFrameBegin((offset: number) => {
            if ((this.listPosition == 0 && offset <= 0) || (this.listPosition == 2 && offset >= 0)) {
              this.scrollerForScroll.scrollBy(0, offset);
              return { offsetRemain: 0 };
            }
            this.listPosition = 1;
            return { offsetRemain: offset };
          })

          Text("Scroll Area")
            .width("100%")
            .height("40%")
            .backgroundColor(0X330000FF)
            .fontSize(16)
            .textAlign(TextAlign.Center)
        }
      }
      .width("100%").height("100%")
    }.width('100%').height('100%').backgroundColor(0xDCDCDC).padding(20)
  }
}

示例图片

参考文档:常见列表操作-布局与弹窗 - 华为HarmonyOS开发者

通过设置嵌套滚动模式与动态布局控制,可实现Scroll嵌套List时只滑动外层Scroll容器。以下是具体方法:

通过 nestedScroll 属性强制父容器优先处理滚动事件:

List() {
  // List内容...
}
.nestedScroll({
  scrollForward: NestedScrollMode.PARENT_FIRST, // 向前滚动时父容器优先
  scrollBackward: NestedScrollMode.PARENT_FIRST // 向后滚动时父容器优先
})

将父容器(Scroll)与子组件(List)的滚动优先级设为父容器优先,确保手指滑动时父容器始终优先响应。

通过 NestedScrollMode.PARENT_FIRST 模式,List组件不会触发自身滚动逻辑。

解决方案

通过nestedScroll属性指定父容器优先处理滚动事件:

Scroll(this.scroller) {

  List() {

    // List内容

  }

  .width('100%')

}

.nestedScroll({

  scrollForward: NestedScrollMode.PARENT_FIRST, // 向前滚动父容器优先

  scrollBackward: NestedScrollMode.PARENT_FIRST // 向后滚动父容器优先

})

避免为List设置固定高度,改用自适应布局:

List() {

  // List项

}

.width('100%')

.height('auto') // 高度自适应

在HarmonyOS鸿蒙Next中,可通过设置List组件的scrollable属性为false实现仅Scroll滑动。List默认支持独立滑动,禁用后其滚动事件由外层Scroll容器统一处理。需确保List高度固定或由内容撑开,避免布局冲突。

在HarmonyOS Next中,可以通过以下方式实现scroll嵌套list时只滑动整个scroll容器:

  1. 在list组件上设置scrollEnabled属性为false,禁止list自身滑动:
List() {
  // list内容
}
.scrollEnabled(false)
  1. 确保scroll容器能够正确接收和处理滑动事件:
Scroll() {
  List() {
    // list内容
  }
  .scrollEnabled(false)
}
.scrollable(ScrollDirection.Vertical) // 或Horizontal

这样配置后,所有滑动操作将由外层的scroll容器处理,list内部的item不会独立滚动。

回到顶部