当前位置: 首页 > article >正文

【每日学点HarmonyOS Next知识】拖拽调整列表顺序、tab回弹、自定义弹窗this、状态变量修饰枚举

1、HarmonyOS 功能实现(拖拽调整列表顺序)?

可参考:

import curves from '@ohos.curves';
import Curves from '@ohos.curves'

@Entry
@Component
struct ListItemExample {
  @State private arr: number[] = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
  @State dragItem: number = -1
  @State scaleItem: number = -1
  @State neighborItem: number = -1
  @State neighborScale: number = -1
  private dragRefOffset: number = 0
  @State offsetX: number = 0
  @State offsetY: number = 0
  private ITEM_INTV: number = 120
  scaleSelect(item: number): number {
    if (this.scaleItem == item) {
      return 1.05
    } else if (this.neighborItem == item) {
      return this.neighborScale
    } else {
      return 1
    }
  }
  itemMove(index: number, newIndex: number): void {
    let tmp = this.arr.splice(index, 1)
    this.arr.splice(newIndex, 0, tmp[0])
  }
  build() {
    Stack() {
      List({ space: 20, initialIndex: 0 }) {
        ForEach(this.arr, (item: number) => {
          ListItem() {
            Text('' + item)
              .width('100%')
              .height(100)
              .fontSize(16)
              .textAlign(TextAlign.Center)
              .borderRadius(10)
              .backgroundColor(0xFFFFFF)
              .shadow(this.scaleItem == item ? { radius: 70, color: '#15000000', offsetX: 0, offsetY: 0 } :
                { radius: 0, color: '#15000000', offsetX: 0, offsetY: 0 })
              .animation({ curve: Curve.Sharp, duration: 300 })
          }
          .margin({ left: 12, right: 12 })
          .scale({ x: this.scaleSelect(item), y: this.scaleSelect(item) })
          .zIndex(this.dragItem == item ? 1 : 0)
          .translate(this.dragItem == item ? { y: this.offsetY } : { y: 0 })
          .gesture(
            // 以下组合手势为顺序识别,当长按手势事件未正常触发时则不会触发拖动手势事件
            GestureGroup(GestureMode.Sequence,
              LongPressGesture({ repeat: true })
                .onAction((event?: GestureEvent) => {
                  animateTo({ curve: Curve.Friction, duration: 300 }, () => {
                    this.scaleItem = item
                  })
                })
                .onActionEnd(() => {
                  animateTo({ curve: Curve.Friction, duration: 300 }, () => {
                    this.scaleItem = -1
                  })
                }),
              PanGesture({ fingers: 1, direction: null, distance: 0 })
                .onActionStart(() => {
                  this.dragItem = item
                  this.dragRefOffset = 0
                })
                .onActionUpdate((event: GestureEvent) => {
                  this.offsetY = event.offsetY - this.dragRefOffset
                  // console.log('Y:' + this.offsetY.toString())
                  this.neighborItem = -1
                  let index = this.arr.indexOf(item)
                  let curveValue = Curves.initCurve(Curve.Sharp)
                  let value: number = 0
                  //根据位移计算相邻项的缩放
                  if (this.offsetY < 0) {
                    value = curveValue.interpolate(-this.offsetY / this.ITEM_INTV)
                    this.neighborItem = this.arr[index-1]
                    this.neighborScale = 1 - value / 20;
                    console.log('neighborScale:' + this.neighborScale.toString())
                  } else if (this.offsetY > 0) {
                    value = curveValue.interpolate(this.offsetY / this.ITEM_INTV)
                    this.neighborItem = this.arr[index+1]
                    this.neighborScale = 1 - value / 20;
                  }
                  //根据位移交换排序
                  if (this.offsetY > this.ITEM_INTV / 2) {
                    animateTo({ curve: curves.interpolatingSpring(0, 1, 400, 38) }, () => {
                      this.offsetY -= this.ITEM_INTV
                      this.dragRefOffset += this.ITEM_INTV
                      this.itemMove(index, index + 1)
                    })
                  } else if (this.offsetY < -this.ITEM_INTV / 2) {
                    animateTo({ curve: curves.interpolatingSpring(0, 1, 400, 38) }, () => {
                      this.offsetY += this.ITEM_INTV
                      this.dragRefOffset -= this.ITEM_INTV
                      this.itemMove(index, index - 1)
                    })
                  }
                })
                .onActionEnd((event: GestureEvent) => {
                  animateTo({ curve: curves.interpolatingSpring(0, 1, 400, 38) }, () => {
                    this.dragItem = -1
                    this.neighborItem = -1
                  })
                  animateTo({
                    curve: curves.interpolatingSpring(14, 1, 170, 17), delay: 150
                  }, () => {
                    this.scaleItem = -1
                  })
                })
            )
              .onCancel(() => {
                animateTo({ curve: curves.interpolatingSpring(0, 1, 400, 38) }, () => {
                  this.dragItem = -1
                  this.neighborItem = -1
                })
                animateTo({
                  curve: curves.interpolatingSpring(14, 1, 170, 17), delay: 150
                }, () => {
                  this.scaleItem = -1
                })
              })
          )
        }, (item: number) => item.toString())
      }
    }.width('100%').height('100%').backgroundColor(0xDCDCDC).padding({ top: 5 })
  }}
2、HarmonyOS tab组件滑到最后一个index的时候,可以关闭回弹效果吗?

tab组件滑倒最后一个index的时候,可以关闭回弹效果吗

边缘tab继续滑动可以通过给TabContent添加手势进行限制。参考方案如下: 最左侧的TabContent添加.gesture(PanGesture(new PanGestureOptions({ direction: PanDirection.Right }))),限制组件内置的右滑动。 最右侧的TabContent添加.gesture(PanGesture(new PanGestureOptions({ direction: PanDirection.Left }))),限制组件内置的左滑动。参考demo:

@Entry
@Component
struct TabsExample {
  private controller: TabsController = new TabsController();

  build() {
    Column() {
      Tabs({ barPosition: BarPosition.Start, controller: this.controller }) {
        TabContent() {
          Column()
            .width('100%')
            .height('100%')
            .backgroundColor(Color.Green)
        }
        .tabBar('green')
        .gesture(PanGesture(new PanGestureOptions({ direction: PanDirection.Right })))

        TabContent() {
          Column()
            .width('100%')
            .height('100%')
            .backgroundColor(Color.Blue)
        }
        .tabBar('blue')
        .gesture(PanGesture(new PanGestureOptions({ direction: PanDirection.Left })))

        // ...

      }
      .barMode(BarMode.Scrollable)
      .barWidth('100%')
      .barHeight(60)
      .width('100%')
      .height('100%')
      .backgroundColor(0xF5F5F5)
    }
  }
}
3、HarmonyOS 自定义弹窗是否可以不绑定 this ?

可以尝试将弹窗设置成全局,可以不使用this

自定义弹窗不需要绑定this

4、HarmonyOS @State 是不是不能修饰枚举?

@State 是不是不能修饰枚举?修饰了枚举会报错:[nodict][page_router_manager.cpp(LoadPage)-(100000:100000:scope)] Update RootComponent Failed or LoadNamedRouter Failed

在ArkTS中,不支持使用declare关键字修饰类。这意味着如果在struct页面中创建了使用declare关键字修饰的类,可能会导致一些问题,包括@State修饰的枚举报错。具体原因如下:

  1. 不支持declare关键字:ArkTS不支持使用declare关键字定义类。这是因为declare关键字主要用于声明变量或类型,而不是定义类。因此,如果你在struct页面中使用declare关键字定义类,会导致编译错误。
  2. @State修饰枚举报错:由于类使用了declare关键字,导致类的定义不符合ArkTS的规范,从而引发编译错误。这可能会影响其他依赖该类的代码,包括使用@State修饰的枚举。
5、HarmonyOS loading 跨页面实现方式?

可以在页面转换时加入一个闪屏页实现,通过router.replaceUrl用需要切换的页面替换这个闪屏页实现,如:

@Entry
@Component
export struct LoadingPage {
  @Prop flag: boolean;

  build() {
    Row() {
      LoadingProgress().color(Color.White).width(50).height(50)
    }
    .height(this.flag ? '100%' : 0)
    .width('100%')
    .position({ x: 0, y: 0 })
    .backgroundColor('#4D000000')
    .justifyContent(FlexAlign.Center)
  }
}

replaceUrl参考文档:https://developer.huawei.com/consumer/cn/doc/harmonyos-references-V5/js-apis-router-V5


http://www.kler.cn/a/582222.html

相关文章:

  • 工作中,当遇到要把http请求变成https时 怎么处理
  • spring 的model repository service controller的功能
  • Yashan DB 文件管理
  • 《深度剖析架构蒸馏与逻辑蒸馏:探寻知识迁移的差异化路径》
  • 【音视频】ffmpeg命令提取像素格式
  • 20250212:linux系统DNS解析卡顿5秒的bug
  • 在 Spring Boot 2.7.x 中引入 Kafka-0.9 的实践
  • vscode 好用插件
  • MySQL-储存引擎
  • 深度解析:如何在 Vue 3 中安全访问子组件实例
  • 使用STM32CubeMX配置定时器中断实现LED每秒闪烁一次(STM32G070CBT6)
  • windows上传uniapp打包的ipa文件到app store构建版本
  • Selenium 中 ActionChains 支持的鼠标和键盘操作设置及最佳实践
  • 密码学系列 - 利用CPU指令加速
  • 高效自动化测试:打造Python+Requests+Pytest+Allure+YAML的接口测试框架
  • 鸿蒙NEXT开发-自定义相机拍照
  • 小程序 wxml 语法 —— 42 条件渲染
  • JavaScript 模块 vs C# 类:封装逻辑的两种哲学
  • 【社交+陪玩服务】全场景陪玩系统源码 小程序+H5双端 社群互动+即时点单+搭建教程
  • Linux 进程信息查看