基于滚动组件的手势处理

基于滚动组件的手势处理

HarmonyOS
2024-07-25 10:19:57
浏览
收藏 0
回答 1
回答 1
按赞同
/
按时间
day_night

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

效果图

方案

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

核心代码

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('跳转') 
      } 
    }) 
)
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
  • 21.
  • 22.
  • 23.
  • 24.
  • 25.
  • 26.
  • 27.
  • 28.
  • 29.
  • 30.
  • 31.
  • 32.
  • 33.
  • 34.
  • 35.
  • 36.
  • 37.
  • 38.
  • 39.
  • 40.
  • 41.
  • 42.
  • 43.
  • 44.
  • 45.
  • 46.
  • 47.
  • 48.
  • 49.
  • 50.
  • 51.
  • 52.
  • 53.
  • 54.
  • 55.
  • 56.
  • 57.
  • 58.
  • 59.
  • 60.
  • 61.
  • 62.
  • 63.
  • 64.
  • 65.
  • 66.
  • 67.
  • 68.
  • 69.
  • 70.
  • 71.

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

效果图

方案

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

核心代码

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 
  }) 
})
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
  • 21.
  • 22.
  • 23.
  • 24.
  • 25.
  • 26.
  • 27.
  • 28.
  • 29.
  • 30.
  • 31.
  • 32.
  • 33.
  • 34.
  • 35.
  • 36.
  • 37.
  • 38.
  • 39.
  • 40.
  • 41.
  • 42.
  • 43.
  • 44.
  • 45.
  • 46.
  • 47.
  • 48.
  • 49.
  • 50.
  • 51.
  • 52.
  • 53.
  • 54.
  • 55.
  • 56.
  • 57.
  • 58.
  • 59.
  • 60.
  • 61.
  • 62.
  • 63.
  • 64.
  • 65.
  • 66.
  • 67.
  • 68.
分享
微博
QQ
微信
回复
2024-07-25 18:37:49


相关问题
基于webView嵌套滚动
1038浏览 • 1回复 待解决
HarmonyOS 弹窗后退手势处理问题
863浏览 • 1回复 待解决
基于ImageKit对图片进行处理
1546浏览 • 1回复 待解决
HarmonyOS 手势处理高概率闪退
715浏览 • 1回复 待解决
基于原生能力组件封装
1380浏览 • 1回复 待解决
如何获取List组件滚动滚动距离
3489浏览 • 1回复 待解决
HarmonyOS 手势密码组件
679浏览 • 1回复 待解决
基于Progress组件进度条
1512浏览 • 1回复 待解决
HarmonyOS List组件滚动监听
851浏览 • 1回复 待解决
HarmonyOS 图片组件手势滑动
639浏览 • 1回复 待解决
Web组件如何开启手势缩放
2347浏览 • 1回复 待解决
HarmonyOS Scroll组件滚动控制
931浏览 • 1回复 待解决
HarmonyOS 关于stack组件手势遮盖问题
523浏览 • 1回复 待解决
HarmonyOS web组件拦截返回手势
648浏览 • 1回复 待解决
HarmonyOS 是否有9宫格手势密码组件
712浏览 • 1回复 待解决