HarmonyOS 鸿蒙Next中bindSheet惯性滑动和回弹效果的取消

HarmonyOS 鸿蒙Next中bindSheet惯性滑动和回弹效果的取消

bindSheet的Demo

这是一个bindSheet的Demo,我想设置下滑到web展示的最底部后再次下滑不进行滑动,固定住,不回弹,不惯性滑动,上划到最顶部也是同理,请问大家该怎么做

import { webview } from '@kit.ArkWeb';
import { TouchEvent } from '@kit.InputKit';

// xxx.ets
@Component
struct SheetTransitionExample {
  controller: webview.WebviewController = new webview.WebviewController();

  @State isShow: boolean = false
  @State sheetHeight1: number = 500
  @State sheetHeight2: number = 1000
  @State detentsSelection: number = 500
  @State canGesture: Boolean = true
  halfHeight: number = 0
  private panOption: PanGestureOptions = new PanGestureOptions({ direction: PanDirection.Up })

  @Builder
  myBuilder() {
    Column() {
      Button("content1")
        .onClick(() => {
          this.detentsSelection = 1000
          console.log("当前点击selection" + this.detentsSelection.toString())
          this.canGesture = false
        })
        .margin(10)
        .fontSize(20)
      Button("content2")
        .onClick(() => {
          this.detentsSelection = 500
          this.canGesture = true
        })
        .margin(10)
        .fontSize(20)
      Web({
        src: "https://developer.harmonyos.com",
        controller: this.controller
      })
        .width('100%')
        .height('100%')
        .gesture(PanGesture(this.panOption)
          .onActionStart((event: GestureEvent) => {
            console.info('Pan start,Up3')
          })
        )
        .nestedScroll({
          // 可滚动组件往末尾端滚动时的嵌套滚动选项,手势向上
          scrollForward: NestedScrollMode.PARENT_FIRST,
          // 可滚动组件往起始端滚动时的嵌套滚动选项,手势向下
          scrollBackward: NestedScrollMode.SELF_FIRST,
        })
        .onTouch((event) => {
          if (event.type === TouchType.Up) {
            console.log("Pan start touch")
          }
        })
        .onGestureJudgeBegin(() => {
          if (this.canGesture){
            return GestureJudgeResult.CONTINUE
          } else{
            return GestureJudgeResult.REJECT
          }
        })
    }
    .width('100%')
    .backgroundColor(Color.Black)

    .gesture(PanGesture(this.panOption)
      .onActionStart((event: GestureEvent) => {
        console.info('Pan start,Up2')
      })
    )
  }

  build() {
    Column() {
      Button("transition modal 1")
        .onClick(() => {
          this.isShow = true
        })
        .fontSize(20)
        .margin(10)
        .bindSheet($$this.isShow, this.myBuilder(), {
          detentSelection: this.detentsSelection,
          detents :[this.sheetHeight1,this.sheetHeight2],
          scrollSizeMode: 1,
          backgroundColor: Color.Blue,
          blurStyle: BlurStyle.Thick,
          showClose: true,
          onHeightDidChange:(height:number) =>{
            if(this.halfHeight===0){
              this.halfHeight = height
            }
            if(this.halfHeight===height){
              this.detentsSelection = 500
            }
          },
          onDetentsDidChange:(height:number) =>{
            if(this.halfHeight===height){
              this.detentsSelection = 500
            } else{
              this.detentsSelection = 1000
            }
            console.log("当前selection"+this.detentsSelection.toString()+"当前height"+height.toString())
          },
          onDisappear:() =>{
            this.detentsSelection = 500
          }
        })
    }
    .width('100%')
    .height('100%')
  }
}

更多关于HarmonyOS 鸿蒙Next中bindSheet惯性滑动和回弹效果的取消的实战教程也可以访问 https://www.itying.com/category-93-b0.html

4 回复

鸿蒙系统 bindSheet 滑动限制解决方案

想要限制 bindSheet 在 WebView 滚动到底部或顶部后的继续滑动行为,取消惯性和回弹效果。这是一个常见的需求,特别是在混合内容应用中。

在鸿蒙系统中,可以通过以下方式实现这个功能:

实现原理

这个解决方案的核心思路是:

  1. 检测WebView滚动位置

    • 使用JavaScript接口和注入的脚本检测WebView是否滚动到顶部或底部
    • 当滚动位置变化时,通过JavaScript接口将状态传递回ETS代码
  2. 控制手势传播

    • onActionUpdate回调中检查当前滚动位置和手势方向
    • 当WebView在底部且用户继续下滑,或在顶部且用户继续上滑时,拒绝手势传播
  3. 取消惯性和回弹

    • 通过在适当的时候拒绝手势传播,阻止系统继续处理滑动
    • 这实际上取消了惯性滑动效果,因为系统不再接收持续的滑动事件

关键修改点

  1. 添加了两个状态变量:

    [@State](/user/State) isWebAtTop: Boolean = true
    [@State](/user/State) isWebAtBottom: Boolean = false
    
  2. 为WebView添加了JavaScript接口和滚动检测代码:

    .addJavaScriptInterface(...)
    .onPageEnd(() => {...})
    
  3. 在手势更新时添加了条件判断:

    .onActionUpdate((event: GestureEvent) => {
        if ((this.isWebAtBottom && event.offsetY > 0) ||
            (this.isWebAtTop && event.offsetY < 0)) {
            return GestureJudgeResult.REJECT;
        }
        return GestureJudgeResult.CONTINUE;
    })
    

如果这种方法在实际应用中仍有问题,你可能需要考虑使用更底层的API或尝试不同的滚动模式配置。根据你的具体需求,可能还需要调整检测滚动位置的逻辑。

更多关于HarmonyOS 鸿蒙Next中bindSheet惯性滑动和回弹效果的取消的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html


并不是很好用,

并不是很好用,

在HarmonyOS鸿蒙Next中取消bindSheet的惯性滑动和回弹效果,可通过修改sheet组件的属性实现。将bounce和friction属性设置为false0即可关闭回弹和惯性滑动效果。

示例代码:

bindSheet({
  bounce: false,
  friction: 0
})

这两个参数分别控制回弹效果和滑动阻力,设置为上述值后,bindSheet将立即停止无动画效果。该配置适用于需要精确控制滚动的场景。

在HarmonyOS Next中,要取消bindSheet的惯性滑动和回弹效果,可以通过以下方式实现:

  1. 在bindSheet的配置中,设置scrollSizeMode为0(禁用滚动):
.bindSheet($$this.isShow, this.myBuilder(), {
  scrollSizeMode: 0,  // 禁用滚动
  // 其他配置...
})
  1. 通过手势控制来限制滑动行为,在你的代码中已经实现了部分控制逻辑。可以进一步完善onGestureJudgeBegin回调:
.onGestureJudgeBegin(() => {
  const currentHeight = this.controller.getCurrentHeight(); // 获取当前高度
  const isAtTop = currentHeight <= this.sheetHeight1;
  const isAtBottom = currentHeight >= this.sheetHeight2;
  
  if((isAtTop && direction === 'down') || 
     (isAtBottom && direction === 'up') || 
     !this.canGesture) {
    return GestureJudgeResult.REJECT;
  }
  return GestureJudgeResult.CONTINUE;
})
  1. 在onHeightDidChange回调中添加边界检查:
onHeightDidChange: (height: number) => {
  if(height <= this.sheetHeight1) {
    this.detentsSelection = 500;
  } else if(height >= this.sheetHeight2) {
    this.detentsSelection = 1000;
  }
}

这些修改将确保当sheet滑动到顶部或底部时,不会再产生惯性滑动或回弹效果。

回到顶部