HarmonyOS Next开发----k线图滑动问题

本文讲述了在开发股票软件鸿蒙版本时,如何实现K线趋势图的滑动和惯性滑动效果,作者尝试了借鉴Flutter的Scroll和自定义PanGesture,以及处理长按和缩放手势的过程。
摘要由CSDN通过智能技术生成

前言

最近做股票软件鸿蒙版本的适配,K线趋势图的手势交互上遇到了问题,这里记录下~

功能需求:

实现k线趋势图滑动及fling的效果

思路:

1. 借鉴Flutter版本的思路,在K线趋势图上面叠加一个Scroll布局,使用系统提供给我们的Scroller来计算手势滑动及fling效果。
2. 监听滑动手势PanGesture来处理,fling的惯性滑动效果需要自己模拟计算。

 Scroll(this.mScroller) {
        Text('').width('100%')
      }
      .onAreaChange((oldValue: Area, newValue: Area)=>{
        this.mScroller.scrollEdge(Edge.End)
      })
      .height('100%')
      .width(this.getTotalKLineWidth() + 200)
      .scrollable(ScrollDirection.Horizontal)
      .scrollBar(BarState.On)
      .friction(0.5)
      .onScroll((xOffset, yOffset)=>{
          let result: boolean = this.mGestureHelper.scroll(this.mScroller.currentOffset().xOffset, this.getTotalKLineWidth());
          if (result) {
            this.onDraw();
          }
      })
      .gesture(GestureGroup(GestureMode.Parallel,
        LongPressGesture()
          .onAction((event?: GestureEvent) => {
            if (!this.mCanHorizontalScroll) {
              this.mCanHorizontalScroll = true;
            }
            this.setCrossState(UPMarketUIGestureHelper.CROSS_STATE_SHOW);
            this.mGestureHelper.updateCrossPoint(event?.fingerList[0].localX, event?.fingerList[0].localY);
            this.onDraw();
          })
          .onActionEnd((event?: GestureEvent) => {
            this.setCrossState(UPMarketUIGestureHelper.CROSS_STATE_NORMAL);
            this.onDraw();
          })
          .onActionCancel((event?: GestureEvent) => {
            this.setCrossState(UPMarketUIGestureHelper.CROSS_STATE_NORMAL);
            this.onDraw();
          })
      ), GestureMask.Normal)

由于k线趋势图初始位置是展示最新的k线,然而Scroller不能设置初始位置,尝试在onAreaChange中滑动到最后,但是会有动画效果,所以这个思路实现不了。

使用平移手势接口:

.gesture(GestureGroup(GestureMode.Parallel,
      PanGesture({ direction: this.mCanHorizontalScroll ? PanDirection.All : PanDirection.Horizontal, distance: 1})
        .onActionStart(() => {
          if (!this.mIsLongPressed) {
             this.mGestureHelper.startScroll();
          }
        })
        .onActionEnd(() => {
          this.mGestureHelper.stopScroll();
          this.onDraw();
        })
        .onActionUpdate((event?: GestureEvent) => {
          if (event) {
            if (this.mIsLongPressed) {
              let reallyOffsetX: number = event.offsetX - this.mLastOffsetX;
              let reallyOffsetY: number = event.offsetY - this.mLastOffsetY;
              this.mLastOffsetX = event.offsetX;
              this.mLastOffsetY = event.offsetY;

              this.mCrossTouchPoint.offset(reallyOffsetX, reallyOffsetY);
              this.mCrossTouchPoint.y = Math.max(this.mMainRenderTitleHeight + 1, this.mCrossTouchPoint.y);
              this.mCrossTouchPoint.y = Math.min(this.totalHeight - 1, this.mCrossTouchPoint.y);
              this.mGestureHelper.updateCrossPoint(this.mCrossTouchPoint.x, this.mCrossTouchPoint.y);
              this.onDraw();
            } else {
              if (this.mGestureHelper.scroll(event.offsetX, this.totalWidth)) {
                this.onDraw();
              }
            }
          }
        }),
      LongPressGesture()
        .onAction((event?: GestureEvent) => {
          if (!this.mCanHorizontalScroll) {
            this.mCanHorizontalScroll = true;
          }
          this.setCrossState(UPMarketUIGestureHelper.CROSS_STATE_SHOW);
          this.mCrossTouchPoint.set(event?.fingerList[0].localX, event?.fingerList[0].localY);
          this.mGestureHelper.updateCrossPoint(this.mCrossTouchPoint.x, this.mCrossTouchPoint.y);
          this.onDraw();
        })
        .onActionEnd((event?: GestureEvent) => {
          this.setCrossState(UPMarketUIGestureHelper.CROSS_STATE_NORMAL);
          this.onDraw();
        })
        .onActionCancel((event?: GestureEvent) => {
          this.setCrossState(UPMarketUIGestureHelper.CROSS_STATE_NORMAL);
          this.onDraw();
        }),
      PinchGesture()
        .onActionStart(() => {
          this.mGestureHelper.startScale();
        })
        .onActionUpdate((event) => {
          console.log("UPMarketUISDK  PinchGesture scale: " + event.scale);
          if(this.mGestureHelper.scale(event.scale)) {
            this.onDraw();
          }
        })
    ), GestureMask.Normal)

使用PanGesture也可以实现滑动效果,但是松手惯性滑动需要自己计算。
在这里插入图片描述

  • 10
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 8
    评论
评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值