HarmonyOS Scroll里嵌套list拖动问题?

Scroll里嵌套list,list 滚到到边缘,手指未抬起继续拖动,Scroll能否不响应拖动

需要等到手指抬起再按下拖动时,才响应拖动

阅读 570
1 个回答

参考示例:

// xxx.ets
import { curves } from '@kit.ArkUI'

@Entry
@Component
struct ScrollExample {
  scroller: Scroller = new Scroller()
  private arr: number[] = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
  private childRecognizer: GestureRecognizer = new GestureRecognizer()
  private currentRecognizer: GestureRecognizer = new GestureRecognizer()
  private lastOffset: number = 0

  build() {
    Scroll(this.scroller) {
      Column() {
        Text('test').width('100%').height(50).backgroundColor(Color.Brown)
        List({ space: 20, initialIndex: 0 }) {
          ForEach(this.arr, (item: number) => {
            ListItem() {
              Text('' + item)
                .width('100%')
                .height(100)
                .fontSize(16)
                .textAlign(TextAlign.Center)
                .borderRadius(10)
                .backgroundColor(0xFFFFFF)
            }
          }, (item: string) => item)
        }
        .id("inner")
        .nestedScroll({
          scrollForward: NestedScrollMode.PARENT_FIRST,
          scrollBackward: NestedScrollMode.SELF_ONLY
        })
        .edgeEffect(EdgeEffect.None)
        .backgroundColor(Color.Black)
        .listDirection(Axis.Vertical) // 排列方向
        .scrollBar(BarState.Off)
        .friction(0.6)
        .divider({
          strokeWidth: 2,
          color: 0xFFFFFF,
          startMargin: 20,
          endMargin: 20
        }) // 每行之间的分界线
        .onScrollIndex((firstIndex: number, lastIndex: number, centerIndex: number) => {
          console.info('first' + firstIndex)
          console.info('last' + lastIndex)
          console.info('center' + centerIndex)
        })
      }.height(400)
    }
    .id("outer")
    .shouldBuiltInRecognizerParallelWith((current: GestureRecognizer, others: Array<GestureRecognizer>) => {
      for (let i = 0; i < others.length; i++) {
        let target = others[i].getEventTargetInfo();
        if (target) {
          if (target.getId() == "inner" && others[i].isBuiltIn() &&
            others[i].getType() == GestureControl.GestureType.PAN_GESTURE) { // 找到将要组成并行手势的识别器
            this.currentRecognizer = current; // 保存当前组件的识别器
            this.childRecognizer = others[i]; // 保存将要组成并行手势的识别器
            return others[i]; // 返回将要组成并行手势的识别器
          }
        }
      }
      return undefined;
    })
    .onGestureRecognizerJudgeBegin((event: BaseGestureEvent, current: GestureRecognizer,
      others: Array<GestureRecognizer>) => { // 在识别器即将要成功时,根据当前组件状态,设置识别器使能状态
      if (current) {
        let target = current.getEventTargetInfo();
        if (target) {
          if (target.getId() == "outer" && current.isBuiltIn() &&
            current.getType() == GestureControl.GestureType.PAN_GESTURE) {
            if (others) {
              for (let i = 0; i < others.length; i++) {
                let target = others[i].getEventTargetInfo() as ScrollableTargetInfo;
                if (target instanceof ScrollableTargetInfo && target.getId() == "inner") { // 找到响应链上对应并行的识别器
                  let panEvent = event as PanGestureEvent;
                  if (target.isEnd()) { // 根据当前组件状态以及移动方向动态控制识别器使能状态
                    if (panEvent && panEvent.offsetY < 0) {
                      this.childRecognizer.setEnabled(false)
                      this.currentRecognizer.setEnabled(true)
                    } else {
                      this.childRecognizer.setEnabled(true)
                      this.currentRecognizer.setEnabled(false)
                    }
                  } else if (target.isBegin()) {
                    if (panEvent.offsetY > 0) {
                      this.childRecognizer.setEnabled(false)
                      this.currentRecognizer.setEnabled(true)
                    } else {
                      this.childRecognizer.setEnabled(true)
                      this.currentRecognizer.setEnabled(false)
                    }
                  } else {
                    this.childRecognizer.setEnabled(true)
                    this.currentRecognizer.setEnabled(false)
                  }
                }
              }
            }
          }
        }
      }
      return GestureJudgeResult.CONTINUE;
    })
    .parallelGesture( // 绑定一个Pan手势作为动态控制器
      PanGesture()
        .onActionUpdate((event: GestureEvent) => {
          if (this.childRecognizer.getState() != GestureRecognizerState.SUCCESSFUL ||
            this.currentRecognizer.getState() != GestureRecognizerState.SUCCESSFUL) { // 如果识别器状态不是SUCCESSFUL,则不做控制
            return;
          }
          let target = this.childRecognizer.getEventTargetInfo() as ScrollableTargetInfo;
          let currentTarget = this.currentRecognizer.getEventTargetInfo() as ScrollableTargetInfo;
          if (target instanceof ScrollableTargetInfo && currentTarget instanceof ScrollableTargetInfo) {
            console.log('TestPage:' + 'target.isEnd:' + target.isEnd());
            console.log('TestPage:' + 'target.isBegin:' + target.isBegin());
            console.log('TestPage:' + 'currentTarget.isEnd:' + currentTarget.isEnd());
            console.log('TestPage:' + 'currentTarget.isBegin:' + currentTarget.isBegin());
            console.log('TestPage:' + 'event.offsetY:' + event.offsetY);
            console.log('TestPage:' + 'this.lastOffset:' + this.lastOffset);
          }
          this.lastOffset = event.offsetY
        })
    )
    .height(400)
    .width('100%')
    .position({ left: 0, bottom: 0 })
    .scrollable(ScrollDirection.Vertical) // 滚动方向纵向
    .friction(0.6)
    .scrollBar(BarState.Off)
    .edgeEffect(EdgeEffect.None)
    .padding({ top: 200 })
    .onWillScroll((xOffset: number, yOffset: number, scrollState: ScrollState) => {
      console.info(xOffset + ' ' + yOffset)
    })
    .onScrollEdge((side: Edge) => {
      console.info('To the edge')
    })
    .onScrollStop(() => {
      console.info('Scroll Stop')
    })
    .backgroundColor(Color.Transparent)
  }
}
撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进