首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >HarmonyOS 开发实践 —— 基于滚动组件的手势处理

HarmonyOS 开发实践 —— 基于滚动组件的手势处理

原创
作者头像
小帅聊鸿蒙
发布2024-12-05 15:53:18
发布2024-12-05 15:53:18
3460
举报
文章被收录于专栏:鸿蒙开发笔记鸿蒙开发笔记

场景一:实现左滑阻尼效果

效果图

方案 

在List组件上绑定滑动手势,在List里面最后一个ListItem内部放入Ellipse和Text组件,在滑动手势onActionUpdate回调里控制ListItemGroup组件的offset属性left参数和Ellipse的宽度达到左滑阻尼的效果。

核心代码

代码语言:ts
复制
List({ initialIndex: 0, scroller: this.scroller }) {
  ListItemGroup({ space: 20 }) {
    ForEach(this.arr, (item: number) => {
      ListItem() {
        Text('' + item)
          .width(80)
          .height(100)
          .fontSize(16)
          .textAlign(TextAlign.Center)
          .borderRadius(10)
          .backgroundColor(0xFFFFFF)
      }
    }, (item: string) => item)
  }
  .offset({ left: this.offsetLeft })
 
  ListItem() {
    this.itemEnd()
  }
}
.width('100%')
.height(120)
.scrollBar(BarState.Off)
.listDirection(Axis.Horizontal)
.edgeEffect(EdgeEffect.None)
.backgroundColor(0xDCDCDC)
.padding(10)
.onReachEnd(() => {
  this.isEnd = true
  console.log('is end')
})
.onScrollFrameBegin((offset: number) => {
  console.log('offset', offset)
  if (!this.scroller.isAtEnd()) {
    this.isEnd = false
  }
  if (this.ellipseWidth > 0) {
    return { offsetRemain: 0 }
  }
  return { offsetRemain: offset }
})
.parallelGesture(
  PanGesture({ direction: PanDirection.Horizontal, distance: 1 })
    .onActionStart(() => {
      this.slidOffsetX = 0
    })
    .onActionUpdate((event: GestureEvent) => {
      if (event && this.isEnd) {
        // 限制offsetLeft大于-60小于0
        if (event.offsetX - this.slidOffsetX < -60) {
          this.offsetLeft = -60
        } else if (event.offsetX - this.slidOffsetX > 0) {
          this.offsetLeft = 0
        } else {
          this.offsetLeft = event.offsetX - this.slidOffsetX
        }
        this.ellipseWidth = (-this.offsetLeft) / 1.5
      } else {
        // 已滑动的偏移量x保存下来,用于处理还未至底部就开始滑动的情况
        this.slidOffsetX = event.offsetX
      }
    })
    .onActionEnd((event: GestureEvent) => {
      console.info('Pan end')
      this.offsetLeft = 0
      this.ellipseWidth = 0
      if (event.offsetX < 0) {
        console.log('跳转')
      }
    })
)

场景二:左滑删除,类似点击弹出 swipeAction 的效果

效果图

方案

在ListItem组件上绑定滑动手势,在滑动手势onActionUpdate事件里控制ListItem的属性offset的参数x的值,在onActionEnd事件里判断当前左滑的偏移量控制是否拉出删除按钮,最后给ListItem绑定点击事件,使用animateTo展开删除按钮。

核心代码

代码语言:ts
复制
ListItem() {
  Row() {
    Text('item' + this.item.num)
      .width('100%')
      .height(100)
      .fontSize(16)
      .textAlign(TextAlign.Center)
      .borderRadius(10)
      .backgroundColor(0xFFFFFF)
    Row() {
      Button('删除')
    }
    .width(120)
    .justifyContent(FlexAlign.Center)
  }
}
.offset({ x: this.item.offsetX })
.transition({ type: TransitionType.Delete, opacity: 0 })
.priorityGesture(
  PanGesture({ direction: PanDirection.Horizontal, distance: 1 })
    .onActionUpdate((event: GestureEvent) => {
      if (this.item.isDelShow) {
        // 删除按钮显示状态
        if (-120 + event.offsetX < -120) {
          this.item.offsetX = -120
        } else if (-120 + event.offsetX > 0) {
          this.item.offsetX = 0
        } else {
          this.item.offsetX = -120 + event.offsetX
        }
      } else {
        // 删除按钮未显示状态
        if (event.offsetX < -120) {
          this.item.offsetX = -120
        } else if (event.offsetX > 0) {
          this.item.offsetX = 0
        } else {
          this.item.offsetX = event.offsetX
        }
      }
    })
    .onActionEnd((_event: GestureEvent) => {
      console.log('this.item.offsetX', this.item.offsetX)
      if (this.item.offsetX > -60) {
        animateTo({
          duration: 300,
        }, () => {
          this.item.offsetX = 0
          this.item.isDelShow = false
        })
      } else {
        animateTo({
          duration: 300,
        }, () => {
          this.item.offsetX = -120
          this.item.isDelShow = true
        })
      }
    })
)
.onClick(() => {
  animateTo({
    duration: 300,
  }, () => {
    this.item.offsetX = -120
    this.item.isDelShow = true
  })
})

写在最后

如果你觉得这篇内容对你还蛮有帮助,我想邀请你帮我三个小忙:

  • 点赞,转发,有你们的 『点赞和评论』,才是我创造的动力;
  • 关注小编,同时可以期待后续文章ing🚀,不定期分享原创知识;
  • 想要获取更多完整鸿蒙最新学习知识点,可关注B站:码牛课堂;

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 场景一:实现左滑阻尼效果
  • 场景二:左滑删除,类似点击弹出 swipeAction 的效果
  • 写在最后
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档