美文网首页
鸿蒙-封装吸边可拖拽视图

鸿蒙-封装吸边可拖拽视图

作者: lkkwxy | 来源:发表于2025-03-25 12:47 被阅读0次

鸿蒙版本:HarmonyOS NEXT/API12+

实现思路

使用绝对定位来控制视图的显示位置,添加拖动手势,在拖动手势对应的事件里去改变视图的位置

封装一个吸边可拖拽的视图,需要考虑以下几点

  1. 需要使用方来定义拖动视图的初始位置
  2. 需要使用方来定义拖动视图的内容
  3. 需要响应视图的拖动事件,并移动视图的位置
  4. 在拖动事件结束之后,需要根据视图当前的位置,去判断吸附到屏幕的哪个边缘,并且以动画的形式滚动到屏幕边缘

1. 需要使用方来定义拖动视图的初始位置

可以使用鸿蒙状态管理V2里的@Param @Once 来定义视图的初始位置,Param @Once 可以实现仅从外部初始化一次、不接受后续同步变化的能力@Param @Once bottom:number = 20; @Param @Once right:number = 0

2. 需要使用方来定义拖动视图的内容

使用@BuilderParam可以从使用方传过来一个自定义的builder,这样使用方可以自定义视图内容

  @BuilderParam
  defaultBuilder: ()=>void

3. 需要响应视图的拖动事件,并移动视图的位置

给视图添加拖动手势,在手势开始时,记录当前的位置,在手势更新时,根据偏移量和开始时的位置,更新视图的位置

4. 在拖动事件结束之后,需要根据视图当前的位置,去判断吸附到屏幕的哪个边缘,并且以动画的形式滚动到屏幕边缘

当视图中心点小于屏幕中心点的时候,需要移动到屏幕左侧,否则移动到屏幕右侧,因此我们需要获取屏幕的宽度以及视图的宽度, 通过display.getDefaultDisplaySync() 获取屏幕信息(获取到的信息是px,需要转换成vp),通过onSizeChange获取视图信息,视图中心点等于屏幕宽度 - right - 视图宽度除以2,最后通过Animator来实现动画

完整代码

import { display } from "@kit.ArkUI"
import { AnimatorResult } from '@kit.ArkUI';

@ComponentV2
export  struct DragView {
  @BuilderParam
  defaultBuilder: ()=>void
  @Param @Once bottom:number = 20
  @Param @Once right:number = 0
  private sizeWidth: number = 0
  private startBottom: number = 0
  private startRight: number = 0
  private screenWidth: number = 0
  private fadeAnimator: AnimatorResult | undefined = undefined

  aboutToAppear(): void {
    //获取屏幕宽度,并转换成VP
    const displayInfo = display.getDefaultDisplaySync()
    this.screenWidth = px2vp(displayInfo.width)
  }

  aboutToDisappear(): void {
    this.fadeAnimator = undefined
  }
  createFadeAnim(begin: number, end: number) {
    // 创建动画,在动画的onFrame里去控制right的值
    this.fadeAnimator = this.getUIContext().createAnimator({
      duration: 300,
      easing:'ease',
      delay:0,
      fill: "forwards",
      direction: "normal",
      iterations: 1,
      begin,
      end
    })
    this.fadeAnimator.onFrame = (value: number) => {
      this.right = value
    }
    this.fadeAnimator.play()
  }
  build() {
    Row(){
      this.defaultBuilder()
    }
    .position({bottom:this.bottom, right:this.right})
    // 获取视图的大小
    .onSizeChange((oldValue, newValue)=>{
      this.sizeWidth = newValue.width as number
    })
    
    //添加手势
    .gesture(
      PanGesture()
        //在手势开始时,取消动画,并记录手势开始时,视图当前位置
        .onActionStart((event: GestureEvent) => {
          this.fadeAnimator?.cancel()
          this.startBottom = this.bottom
          this.startRight = this.right
        })
        // 手势更新时,修改bottom和right的值
        // offsetY向上位负,offsetX向左位负数
        .onActionUpdate((event: GestureEvent) => {
          if (event) {
            this.bottom = this.startBottom - event.offsetY
            this.right = this.startRight - event.offsetX
          }
        })
        //手势结束回调
        .onActionEnd((event: GestureEvent) => {
          // 屏幕中心点
          const screenCenter = this.screenWidth / 2
          // 视图中心点
          const selfCenter = this.screenWidth - this.right - this.sizeWidth / 2
          //最终right的值,屏幕右侧值为0,屏幕左侧值为屏幕宽度减去视图宽度
          let end = selfCenter < screenCenter ? this.screenWidth - this.sizeWidth : 0;
          //创建动画,当前right为起始点,end为动画结束点
          this.createFadeAnim(this.right, end)
        }))
  }
}

相关文章

  • (Swift)吸边可拖拽视图

    一) 使用场景 多用于活动展示; 控件自定义; 支持点击事件; 支持动画效果; 效果如下;ki6jt-zt5b3....

  • MacOS 开发(十六) : 文件拖拽

    文件拖拽的核心是拖拽目标视图 (DragDestinationView),此方法会检测目标是否可拖拽类型,拖拽文件...

  • React Native之组件

    View 视图 实例1 Button 按钮 例1 属性 TouchableHighlight 用来封装可触摸视图 ...

  • OC 二级联动

    今天写了个二级联动,并且可以弹出一个可拖拽的视图,允许拖拽标题,拖拽完成自动交换布局,而且标题宽度自动适配,允许标...

  • 集合视图抖动,拖拽

    集合视图抖动拖拽

  • 自定义拖拽View

    封装简单拖拽视图view,效果如下: 实现思路: 通过箭头的滑动事件坐标动态变化改变容器的高度 上面在箭头Imag...

  • 拖拽库

    拖拽库封装代码

  • 封装移动端 vue 拖拽指令

    封装移动端 vue 拖拽指令 通过vue自定义指令,将拖拽行为封装为指令 使用transform做移动效果,需要注...

  • Angular cdk 学习之 drag-drop

    Angualr drag-drop里面的功能能让我们非常方便的处理页面上视图的拖拽(自由拖拽、列表排序拖拽、...

  • 基于vuedraggable封装的可拖拽树

    一、NPM或yarn安装方式官方文档[http://www.itxst.com/vue-draggable/tut...

网友评论

      本文标题:鸿蒙-封装吸边可拖拽视图

      本文链接:https://www.haomeiwen.com/subject/arwfvjtx.html