【每日学点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

相关推荐
遇到困难睡大觉哈哈9 小时前
HarmonyOS 公共事件机制介绍以及多进程之间的通信实现(9000字详解)
华为·harmonyos
幽蓝计划13 小时前
HarmonyOS NEXT仓颉开发语言实战案例:外卖App
开发语言·harmonyos
伍哥的传说13 小时前
鸿蒙系统(HarmonyOS)应用开发之实现电子签名效果
开发语言·前端·华为·harmonyos·鸿蒙·鸿蒙系统
Georgewu15 小时前
【HarmonyOS】应用开发拖拽功能详解
harmonyos
塞尔维亚大汉15 小时前
鸿蒙内核源码分析(构建工具篇) | 顺瓜摸藤调试鸿蒙构建过程
源码·harmonyos
Fanmeang18 小时前
OSPF高级特性之FRR
运维·网络·华为·ip·ospf·spf·frr
kumalab18 小时前
HarmonyOS ArkTS卡片堆叠滑动组件实战与原理详解(含源码)
华为·harmonyos
别说我什么都不会19 小时前
【OpenHarmony】鸿蒙开发之xml2jsDemo
harmonyos
HarmonyOS_SDK1 天前
HarmonyOS免密认证方案 助力应用登录安全升级
harmonyos
zhanshuo1 天前
鸿蒙操作系统核心特性解析:从分布式架构到高效开发的全景技术图谱
harmonyos