常规绑定手势的方法

使用.gesture属性将手势事件绑定到指定组件。

用gesture绑定PanGesture手势实现图片滑动

private changedIndex: boolean = true;
private zonesList: ZonesItem[] = ZonesViewModel.getZonesList();
@State aheadIndex: number = ZoneConst.HALF_COUNT;
@State marginBottom: number = 0;
 // 计算图片和最上方图片的下标相对差值
  getImgCoefficients(index: number): number {
    let coefficient = this.aheadIndex - index;
    let tempCoefficient = Math.abs(coefficient);
    if (tempCoefficient <= ZoneConst.HALF_COUNT) {
      return coefficient;
    }
    let dataLength = this.zonesList.length;
    let tempOffset = dataLength - tempCoefficient;
    if (tempOffset <= ZoneConst.HALF_COUNT) {
      if (coefficient > 0) {
        return -tempOffset;
      }
      return tempOffset;
    }
    return 0;
  }
// 计算图片y轴方法的偏移量
  getOffSetY(index: number): number {
    let offsetIndex = this.getImgCoefficients(index);
    let tempOffset = Math.abs(offsetIndex);
    let offsetY = this.marginBottom / (tempOffset + 1);
    if (tempOffset === 1) {
      offsetY += -offsetIndex * ZoneConst.MAX_OFFSET_Y;
    } else if (tempOffset === ZoneConst.HALF_COUNT) {
      offsetY += -offsetIndex * (ZoneConst.MAX_OFFSET_Y - ZoneConst.OFFSET_COEFFICIENTS);
    }
    return offsetY;
  }
// 动态滚动切换最上方图片
startAnimation(isUp: boolean): void {
  animateTo({
    duration: Const.SWIPER_DURATION,
  }, () => {
    let dataLength = this.zonesList.length
    let tempIndex = isUp ? this.aheadIndex + 1 : dataLength + this.aheadIndex - 1;
    this.aheadIndex = tempIndex % dataLength;
    this.marginBottom = 0;
  });
}
​
// 判断是否需要切换最上方图片
handlePanGesture(offsetY: number): void {
  if (Math.abs(offsetY) < ZoneConst.MAX_MOVE_OFFSET) {
    this.marginBottom = offsetY;
  } else {
    if (this.changedIndex) {
      return;
    }
    this.changedIndex = true;
    this.startAnimation(offsetY < 0);
  }
}
build() {
 Stack({alignContent:Alignment.Center}) {
        ForEach(this.zonesList, (item: ZonesItem, index: number) => {
          Row() {
            Image(item.xxx)
            }
            ......
              // 图片透明度
              .opacity(1 - Math.min(ZoneConst.HALF_COUNT,
                Math.abs(this.getImgCoefficients(index))) * ZoneConst.OPACITY_COEFFICIENTS)
                .......
                //y轴偏移量
                 .offset({ x: 0, y: this.getOffSetY(index) })
                 ........
                 }
                 .gesture(
        // 添加手势,通过手势实现图片的动态效果
        PanGesture({ direction: PanDirection.Vertical })
          .onActionStart((event: GestureEvent) => {
            this.changedIndex = false;
            this.handlePanGesture(event.offsetY);
          })
          .onActionUpdate((event: GestureEvent) => {
            this.handlePanGesture(event.offsetY);
          })
          .onActionEnd(() => {
            animateTo({
              duration: Const.SWIPER_DURATION,
            }, () => {
              this.marginBottom = 0;
            });
          })
      )
      }

animateTo定义了一个转场动画

animateTo({ duration: 1000 }, () => {
  this.xxx=xxx;
})

图片

 

带优先级的手势绑定方法

使用.priorityGesture属性将手势事件绑定到指定组件上可以实现优先级显示,在父组件上加.priorityGesture属性父子组件使用同一手势事件时优先响应父组件

// xxx.ets
@Entry
@Component
struct Index {
  build() {
    Column() {
      Text('Gesture').fontSize(28)
        .gesture(
          TapGesture()
            .onAction(() => {
              console.info('Text TapGesture is onAction');
            }))
    }
    .height(200)
    .width(250)
    // 设置为priorityGesture时,点击文本区域会忽略Text组件的TapGesture手势事件,优先响应父组件Column的TapGesture手势事件
    .priorityGesture(
      TapGesture()
        .onAction(() => {
          console.info('Column TapGesture is onAction');
        }), GestureMask.IgnoreInternal)
  }
}

并行手势绑定方法

使用 .parallelGesture属性将手势事件绑定到指定组件上可以实现手势事件的并行显示,在父组件加.parallelGesture属性父子组件加同一手势事件是实现并行显示。

// xxx.ets
@Entry
@Component
struct Index {
  build() {
    Column() {
      Text('Gesture').fontSize(28)
        .gesture(
          TapGesture()
            .onAction(() => {
              console.info('Text TapGesture is onAction');
            }))
    }
    .height(200)
    .width(250)
    // 设置为parallelGesture时,点击文本区域会同时响应父组件Column和子组件Text的TapGesture手势事件
    .parallelGesture(
      TapGesture()
        .onAction(() => {
          console.info('Column TapGesture is onAction');
        }), GestureMask.IgnoreInternal)
  }
}

GestureMask枚举说明

Normal :不屏蔽子组件的手势,按照默认手势识别顺序进行识别。

IgnoreInternal:屏蔽子组件的手势,包括子组件上系统内置的手势,如子组件为List组件时,内置的滑动手势同样会被屏蔽。

Logo

社区规范:仅讨论OpenHarmony相关问题。

更多推荐