HarmonyOS 鸿蒙Next 手势组合事件

发布于 1周前 作者 vueper 最后一次编辑是 5天前 来自 鸿蒙OS

当子控件有滚动事件,父控件有拖动事件,怎么使其可以并发存在或者子控件的滚动事件可以传递给父控件?

如下为demo:

const MIN_HEIGHT: number = 200; // 最小高度
const MAX_HEIGHT: number = 600; // 最大高度

@Component
export struct SlideUpPanelWithGesture {
  @State private boxHeight: number = MIN_HEIGHT; // 控件高度
  private isAtTop: boolean = true; // 滚动内容是否在顶部
  private isAtBottom: boolean = false; // 滚动内容是否在底部
  @State private isDragging: boolean = false; // 是否处于拖动模式
  TAG:string = "SlideUpPanelWithGesture"

  build() {
    Column() {
      // 可滚动内容区域
      List() {
        ForEach(this.createArray(20), (item: number) => {
          ListItem() {
            Text(`内容行 ${item}`).fontSize(18).padding(10);
          }
        });
      }
      .height(this.boxHeight) // 动态高度
      .onWillScroll((offset: number, state: ScrollState) => {
        // 检测是否滚动到顶部或底部
        console.info(this.TAG,"onWillScroll.....")
        this.isAtTop = offset <= 0;
        this.isAtBottom = offset >= this.getMaxScrollOffset();
      });

    }
    .backgroundColor(0xf0f0f0)
    .gesture(
      GestureGroup(GestureMode.Parallel,//并行模式
        PanGesture({ direction: PanDirection.Vertical })
          .onActionUpdate((event) => {
            console.info(this.TAG,"onActionUpdate.....")
          })
      )
    );
  }

  // 判断是否可以进入拖动模式
  private shouldDrag(velocityY: number): boolean {
    // 如果在顶部且向下拉,或者在底部且向上拉,则允许拖动
    return (this.isAtTop && velocityY > 0) || (this.isAtBottom && velocityY < 0);
  }

  // 动态调整控件高度
  private adjustBoxHeight(offset: number) {
    this.boxHeight = Math.max(MIN_HEIGHT, Math.min(MAX_HEIGHT, this.boxHeight + offset));
  }

  // 模拟获取内容可滚动的最大偏移量
  private getMaxScrollOffset(): number {
    return 500; // 假设最大滚动距离
  }

  // 创建虚拟内容
  // 辅助方法:生成固定长度的数组
  private createArray(length: number): number[] {
    const array: number[] = [];
    for (let i = 1; i <= length; i++) {
      array.push(i);
    }
    return array;
  }
}

以上的onWillScroll可以被触发,但是onActionUpdate无法被触发。也使用了组合事件,已经设置了并行模式。但是事件无法传递到onActionUpdate。


更多关于HarmonyOS 鸿蒙Next 手势组合事件的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html

5 回复

如果需要父子组件所绑定的手势不发生冲突,均可响应,可以使用并行的方式在父组件绑定手势。

ComponentA() {
    ComponentB()
    .gesture(TapGesture({count: 1}))
}
.parallelGesture(TapGesture({count: 1}))

当父组件以.parallelGesture的形式绑定手势时,父组件和子组件所绑定的手势均可触发。

此时,单击组件list区域范围,Column和list的点击手势均会触发。

const MIN_HEIGHT: number = 200; // 最小高度
const MAX_HEIGHT: number = 600; // 最大高度

@Entry
@Component
export struct SlideUpPanelWithGesture {
  @State private boxHeight: number = MIN_HEIGHT; // 控件高度
  private isAtTop: boolean = true; // 滚动内容是否在顶部
  private isAtBottom: boolean = false; // 滚动内容是否在底部
  @State private isDragging: boolean = false; // 是否处于拖动模式
  TAG: string = "SlideUpPanelWithGesture"

  build() {
    Column() {
      // 可滚动内容区域
      List() {
        ForEach(this.createArray(20), (item: number) => {
          ListItem() {
            Text(`内容行 ${item}`).fontSize(18).padding(10);
          }
        });
      }
      .height(this.boxHeight) // 动态高度
      .onWillScroll((offset: number, state: ScrollState) => {
        // 检测是否滚动到顶部或底部
        console.info(this.TAG, "onWillScroll.....")
        this.isAtTop = offset <= 0;
        this.isAtBottom = offset >= this.getMaxScrollOffset();
      })

    }
    .backgroundColor(0xf0f0f0)
    .parallelGesture(
      GestureGroup(GestureMode.Parallel, //并行模式
        PanGesture({ direction: PanDirection.Vertical })
          .onActionUpdate((event: GestureEvent) => {
            if (event) {
              console.info('fu Pan upadte')
            }
          })
      )
    );
  }

  // 判断是否可以进入拖动模式
  private shouldDrag(velocityY: number): boolean {
    // 如果在顶部且向下拉,或者在底部且向上拉,则允许拖动
    return (this.isAtTop && velocityY > 0) || (this.isAtBottom && velocityY < 0);
  }

  // 动态调整控件高度
  private adjustBoxHeight(offset: number) {
    this.boxHeight = Math.max(MIN_HEIGHT, Math.min(MAX_HEIGHT, this.boxHeight + offset));
  }

  // 模拟获取内容可滚动的最大偏移量
  private getMaxScrollOffset(): number {
    return 500; // 假设最大滚动距离
  }

  // 创建虚拟内容
  // 辅助方法:生成固定长度的数组
  private createArray(length: number): number[] {
    const array: number[] = [];
    for (let i = 1; i <= length; i++) {
      array.push(i);
    }
    return array;
  }
}

更多关于HarmonyOS 鸿蒙Next 手势组合事件的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html


谢谢,可以达到共存。

还想问下,如果想达到一定程度父子手势切换(即某个状态下为父手势生效,某个状态切为子手势),本地将并行模式Parallel—》切为了互斥Exclusive。发现他们并没用互斥,还是会并发拿。

期待HarmonyOS能在未来带来更多创新的技术和理念。

互斥识别,使用组合手势GestureGroup的互斥识别模式。双击事件需放在单击事件前面,互斥识别是按排列顺序来识别,如果单击事件放前面则只会识别到单击事件。参考代码如下: @Entry @Component struct TapGestureExample { build() { Column() { Text(‘Click twice’) .fontSize(28) .gesture(GestureGroup(GestureMode.Exclusive, TapGesture({ count: 2 }) .onAction(() => { console.info(‘TapGesture 2’); }), TapGesture({ count: 1 }) .onAction(() => { console.info(‘TapGesture 1’); }) ) ) } .width(‘100%’) .height(‘100%’) .justifyContent(FlexAlign.Center) .alignSelf(ItemAlign.Center) } }

HarmonyOS 鸿蒙Next 手势组合事件主要通过系统提供的手势识别API来实现。这些API允许开发者定义和检测复杂的手势组合,比如双指缩放、多指滑动等。

在鸿蒙系统中,手势组合事件的处理一般涉及以下几个步骤:

  1. 注册手势监听器:首先,开发者需要在UI组件上注册一个手势监听器,用于捕获用户的手势输入。

  2. 定义手势组合:在监听器中,开发者可以定义需要识别的手势组合,如同时检测两个手指的触摸和移动事件。

  3. 处理手势事件:当系统检测到定义的手势组合时,会触发相应的回调方法。开发者可以在这些回调方法中实现具体的业务逻辑,如响应手势操作来改变界面状态或执行某些功能。

  4. 释放资源:在不再需要手势识别时,开发者应适时释放相关的资源,以避免内存泄漏等问题。

需要注意的是,鸿蒙系统对手势识别的精度和响应速度有较高要求,因此开发者在实现手势组合事件时,应确保代码的高效性和准确性。

如果问题依旧没法解决请联系官网客服,官网地址是:https://www.itying.com/category-93-b0.html 。在这里,你可以获得更专业的技术支持和解决方案。

回到顶部
AI 助手
你好,我是IT营的 AI 助手
您可以尝试点击下方的快捷入口开启体验!