HarmonyOS鸿蒙Next Web滑动惯性问题

HarmonyOS鸿蒙Next Web滑动惯性问题 RelativeContainer绑定了PanGesture,里面包含一个web,迅速滑动触发PanGesture后,web由于惯性出现滚动,设置了scrollable为false也没效果,如何解决

4 回复

开发者您好,您可以在触发手势时调用

this.webController.setScrollable(false, webview.ScrollType.EVENT); // 禁止滚动

手势结束时调用:

this.webController.setScrollable(true); // 开始滚动

示例代码如下:

import webview from '@ohos.web.webview';

@Entry
@ComponentV2
struct Index {;
  private webController: webview.WebviewController = new webview.WebviewController();
  private panOption: PanGestureOptions = new PanGestureOptions({ direction: PanDirection.Vertical }); // 向上滚动


  build() {
    RelativeContainer() {
      Column() {
        Web({
          // 嵌套的Web组件
          src: $rawfile('index.html'),
          controller: this.webController,
        })
          .height('auto')
          .onGestureRecognizerJudgeBegin((event: BaseGestureEvent, current: GestureRecognizer,
            others: Array<GestureRecognizer>) => {
            if (current.isBuiltIn() && current.getType() == GestureControl.GestureType.PAN_GESTURE) {
              return GestureJudgeResult.REJECT;
            }
            return GestureJudgeResult.CONTINUE;
          });
      };
    }
    .height('100%')
    .gesture(
      PanGesture(this.panOption)
        .onActionStart((event: GestureEvent) => {
          console.info('Pan start');
          this.webController.setScrollable(false, webview.ScrollType.EVENT); // 禁止滚动
        })
        .onActionEnd((event: GestureEvent) => {
          console.info('Pan end');
          console.info(`Pan end timeStamp is: ${event.timestamp}`);
          this.webController.setScrollable(true); // 开始滚动
        })
    );
  }
}

如果还是不能解决您的问题,麻烦您这边提供下完整能复现问题的demo吧。

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


PanGesture用于触发拖动手势事件。滑动的最小距离distance默认为5vp,设置distance值为1可提高灵敏度,防止事件错乱。

PanGesture({ direction: PanDirection.Vertical, distance: 1 })

鸿蒙Next中Web滑动惯性由系统WebView组件控制,默认开启惯性滚动。可通过设置WebView的overScrollMode属性或使用WebSettingssetScrollFriction方法调整滑动阻尼系数来调节惯性效果。具体实现需在ArkTS/ETS中配置Web组件参数,无需涉及Java或C语言代码。

在HarmonyOS Next中,当RelativeContainer绑定PanGesture手势,内部嵌套Web组件时,迅速滑动触发的惯性滚动问题,可通过以下方案解决:

  1. 禁用Web组件滚动: 在Web组件属性中设置scrollable(false),并同步禁用其内部滚动链:

    Web({
      src: '...',
      scrollable: false
    })
    .onInterceptKeyEvent((event: KeyEvent) => {
      // 拦截滚动事件
      if (event.keyCode === KeyCode.KEY_DPAD_UP || event.keyCode === KeyCode.KEY_DPAD_DOWN) {
        return true;
      }
      return false;
    })
    
  2. 手势事件隔离处理: 在PanGesture响应函数中主动停止Web组件的滚动传播:

    PanGesture({ distance: 5 })
      .onActionStart(() => {
        // 获取Web组件实例
        webController.stopScroll();
      })
      .onActionUpdate((event: GestureEvent) => {
        // 自定义滑动逻辑
      })
    
  3. 使用Scroll替代方案: 若需保持滚动效果,可将Web内容转换为原生组件,或通过WebView桥接控制滚动行为:

    // 通过JS注入禁用惯性滚动
    webController.runJavaScript(
      `document.body.style.overscrollBehavior = 'none';`
    )
    
  4. 事件冒泡控制: 在RelativeContainer层拦截触摸事件:

    RelativeContainer()
      .gesture(
        PanGesture({})
          .onActionStart(() => {})
          .setHitTestMode(HitTestMode.Block)
      )
    

注意:Web组件的滚动行为受底层Web引擎控制,部分场景需结合WebViewonInterceptRequest回调进行深度控制。建议通过自定义手势与Web内容滚动状态同步来达到最佳交互效果。

回到顶部